sql server 行转列
看了这个需求同事表示很麻烦,列是动态的,多一天多一个订单类型就多一列,我看了下,这不是sql行转列的节奏么。这个还真没搞过。大家pp这个设计是否合理:
1、模拟数据
2、确定思路,网上看了下动态sql实现,自己想了想好像还需要祭出游标神器,一番调式成功了。没有性能问题啊,呵呵,交货了。跟同事说了下思路,他表示看不惯游标里面嵌套游标。好吧,你自己实现吧,偶是有经验的运用游标,不是乱用,爱用不用。呵呵...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | USE [SK_WMS_DB] GO /****** Object: StoredProcedure [dbo].[sp_warehouse_sum_byOrderDate] Script Date : 01/15/2014 17:16:50 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROC [dbo].[sp_warehouse_sum_byOrderDate] AS BEGIN 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_Report END |
3、成果:
写在这里自己备忘,也给同行看看还有更好的方法不,可以随便喷...
作者:数据酷软件
出处:https://www.cnblogs.com/datacool/p/sql_row_2_col_datacool.html
关于作者:20年编程从业经验,持续关注MES/ERP/POS/WMS/工业自动化
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
联系方式: qq:71008973;wx:6857740733
基于人脸识别的考勤系统 地址: https://gitee.com/afeng124/viewface_attendance_ext
自己开发安卓应用框架 地址: https://gitee.com/afeng124/android-app-frame
WPOS(warehouse+pos) 后台演示地址: http://47.239.106.75:8080/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2013-01-15 .net compact framework2.0 Wince智能设备开发项目经验分享 .net拖空间之进阶篇