博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sql server 行转列
阅读量:4342 次
发布时间:2019-06-07

本文共 4673 字,大约阅读时间需要 15 分钟。

 

看了这个需求同事表示很麻烦,列是动态的,多一天多一个订单类型就多一列,我看了下,这不是sql行转列的节奏么。这个还真没搞过。大家pp这个设计是否合理:

1、模拟数据

2、确定思路,网上看了下动态sql实现,自己想了想好像还需要祭出游标神器,一番调式成功了。没有性能问题啊,呵呵,交货了。跟同事说了下思路,他表示看不惯游标里面嵌套游标。好吧,你自己实现吧,偶是有经验的运用游标,不是乱用,爱用不用。呵呵...

 

USE [SK_WMS_DB]GO/****** Object:  StoredProcedure [dbo].[sp_warehouse_sum_byOrderDate]    Script Date: 01/15/2014 17:16:50 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROC [dbo].[sp_warehouse_sum_byOrderDate]ASBEGIN   declare @sql varchar(max)   declare @v_order_flag varchar(10)   declare @v_dt Date   declare @v_report_columnName varchar(60)   --订单类型临时表   SELECT distinct [OrderFlag] INTO #OrderFlag_Info FROM [SK_WMS_DB].[dbo].[Table_Report_Test]    ORDER BY [OrderFlag] DESC   --订单日期临时表   SELECT distinct OrderDT INTO #OrderDT_Info FROM [SK_WMS_DB].[dbo].[Table_Report_Test]    ORDER BY OrderDT   --表头临时表   SELECT CAST(NULL AS DATE) ORDER_DT,          CAST ('' AS varchar(60)) AS REP_COL_NAME,          CAST ('' AS varchar(10)) AS OrderFlag   INTO #REPORT_COLUMN   declare cur_order_flag cursor for select OrderFlag from #OrderFlag_Info   open cur_order_flag   fetch next from cur_order_flag into @v_order_flag    --根据订单类型生成列名	while @@FETCH_STATUS = 0 	   begin		  declare cur_OrderDT cursor for select OrderDT from #OrderDT_Info 		  open cur_OrderDT		  fetch next from cur_OrderDT into @v_dt 		  --日期+订单类型		  while @@FETCH_STATUS = 0 			 begin				INSERT INTO #REPORT_COLUMN				select @v_dt,					   CAST(substring(CONVERT(char(10),@v_dt,102),6,5)+ @v_order_flag as varchar(60)),					   @v_order_flag				fetch next from cur_OrderDT into @v_dt 			 end       		  close cur_OrderDT		  deallocate cur_OrderDT   	      		  INSERT INTO #REPORT_COLUMN  		  select '1901-01-01',CAST(RTRIM(LTRIM(@v_order_flag))+'小计'  as varchar(60)),@v_order_flag      		  fetch next from cur_order_flag into @v_order_flag               	   end    close cur_order_flag    deallocate cur_order_flag       declare @colText varchar(max)	declare cur_tbl cursor for SELECT REP_COL_NAME FROM #REPORT_COLUMN                                WHERE ORDER_DT IS NOT NULL                               --返回结果临时表	SELECT CAST ('' AS VARCHAR(255)) AS 仓库名称,		   CAST ('' AS VARCHAR(255)) AS 库内区域名称,		   CAST ('' AS VARCHAR(255)) AS 物料号码,		   CAST ('' AS VARCHAR(255)) AS 品名,		   CAST ('' AS VARCHAR(255)) AS 包装         	INTO #Result_Report    --循环增加列                           open cur_tbl    fetch next from cur_tbl into @v_report_columnName     while @@FETCH_STATUS = 0      begin       SET @colText = RTRIM(LTRIM(@v_report_columnName))       SET @sql = 'ALTER TABLE #Result_Report ADD ['+@colText+'] [numeric](18, 2) default 0'       EXEC(@sql)       fetch next from cur_tbl into @v_report_columnName      end         close cur_tbl    deallocate cur_tbl      --清空临时表记录    DELETE FROM #Result_Report    --开始准备数据,每个仓库循环一次    declare @WareHouse varchar(60)    declare @qty numeric(18,2)    declare cur_data_fill     cursor for SELECT distinct [WareHouseName] FROM [SK_WMS_DB].[dbo].[Table_Report_Test]    --填充记录                      open cur_data_fill    fetch next from cur_data_fill into @WareHouse     while @@FETCH_STATUS = 0     begin       insert into #Result_Report (仓库名称,库内区域名称,物料号码,品名,包装)       select @WareHouse,'' 库内区域名称,'' 物料号码,'' 品名,'' 包装                     declare cur_sum_qty        cursor for         SELECT REP_COL_NAME,ORDER_DT,OrderFlag FROM #REPORT_COLUMN       WHERE ORDER_DT IS NOT NULL           open cur_sum_qty       fetch next from cur_sum_qty into @v_report_columnName,@v_dt,@v_order_flag       while @@FETCH_STATUS = 0          begin             IF @v_dt <> '1901-01-01'               SELECT @qty = isnull(SUM(t.Qty),0) FROM dbo.Table_Report_Test t               WHERE t.WareHouseName  = @WareHouse                   AND t.OrderDT = @v_dt                  AND t.OrderFlag = @v_order_flag             ELSE                SELECT @qty = isnull(SUM(t.Qty),0) FROM dbo.Table_Report_Test t               WHERE t.WareHouseName  = @WareHouse                                   AND t.OrderFlag = @v_order_flag                                SELECT @sql = 'UPDATE #Result_Report SET ['+LTRIM(RTRIM(@v_report_columnName))+'] = '+CAST(@qty AS VARCHAR) +                           ' WHERE 仓库名称 = '''+@WareHouse+''''             EXEC(@sql)              fetch next from cur_sum_qty into @v_report_columnName,@v_dt,@v_order_flag          end        close cur_sum_qty       deallocate cur_sum_qty        fetch next from cur_data_fill into @WareHouse     end                         close cur_data_fill    deallocate cur_data_fill      --返回结果集    SELECT * FROM #Result_ReportEND

 3、成果:

写在这里自己备忘,也给同行看看还有更好的方法不,可以随便喷...

 

转载于:https://www.cnblogs.com/datacool/p/sql_row_2_col_datacool.html

你可能感兴趣的文章
观看杨老师(杨旭)Asp.Net Core MVC入门教程记录
查看>>
UIDynamic(物理仿真)
查看>>
Windows下安装Redis
查看>>
winform非常实用的程序退出方法!!!!!(转自博客园)
查看>>
centos安装vim
查看>>
linux工作调度(计划任务)
查看>>
新部署到服务器 报 The requested URL /home/profession was not found on this server. 错误
查看>>
hadoop从非HA转到NAMENODE HA时需要注意的一个问题
查看>>
python-9-IO编程
查看>>
【GoLang】转载:我为什么放弃Go语言,哈哈
查看>>
【MySQL】MySQL 如何实现 唯一随机数ID
查看>>
【Redis】Redis分布式集群几点说道
查看>>
HDU2819(KB10-E 二分图最大匹配)
查看>>
mysql主从复制、redis基础、持久化和主从复制
查看>>
文档工具GitBook使用
查看>>
两个链表的第一个公共节点
查看>>
知道这20个正则表达式,能让你少写1,000行代码
查看>>
MariaDB 主从同步与热备(14)
查看>>
推荐的 CSS 书写顺序
查看>>
NIO:与 Buffer 一起使用 Channel
查看>>