经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MS SQL Server » 查看文章
行转列问题(案例)
来源:cnblogs  作者:Insus.NET  时间:2019/5/30 8:54:48  对本文有异议

有网友在网上问:

数据如下:

  1. number createdate username caseno
  2. 1 2018-05-29 18:57:54.150 戴婷 201708220028
  3. 2 2018-07-04 14:28:40.167 戴婷 201708220028
  4. 3 2019-01-02 11:34:53.533 戴婷 201708220028
  5. 4 2019-01-16 18:17:01.313 戴婷 201708220028


期望得到的结果:

  1. username caseno createdate1 createdate2 createdate3 createdate4
  2. 戴婷 201708220028 2018-05-29 18:57:54.150 2018-07-04 14:28:40.167 2019-01-02 11:34:53.533 2019-01-16 18:17:01.313


下面是Insus.NET实现方法:

创建一个临时表,将用来存储最终结果:

 

  1. IF OBJECT_ID('tempdb..#TempRpt') IS NOT NULL DROP TABLE #TempRpt
  2. CREATE TABLE #TempRpt
  3. (
  4. [caseno] bigint,
  5. [username] nvarchar(20)
  6. )
  7. SELECT [caseno],[username] FROM #TempRpt
Source Code

 

接下来,参考这篇《数据表列值转换为逗号分隔字符串https://www.cnblogs.com/insus/p/10848578.html

改写一下:

 

  1. SET ANSI_NULLS ON
  2. GO
  3.  
  4. SET QUOTED_IDENTIFIER ON
  5. GO
  6.  
  7. -- =============================================
  8. -- Author: Insus.NET
  9. -- Create date: 2019-05-29
  10. -- Update date: 2019-05-29
  11. -- Description: 时间表列值转换为逗号分隔字符串
  12. -- =============================================
  13. CREATE PROCEDURE [dbo].[usp_DateColumnToCommaDelimitedString] (
  14. @TableName SYSNAME,
  15. @DateColumn SYSNAME,
  16. @Comma_Delimited_String NVARCHAR(MAX) OUTPUT
  17. )
  18. AS
  19. BEGIN
  20. DECLARE @query NVARCHAR(MAX) = N'SET @Comma_Delimited_String = STUFF((SELECT DISTINCT '','' + QUOTENAME(CAST('+ @DateColumn +' AS DATE))
  21. FROM '+ @TableName +'
  22. FOR XML PATH(''''), TYPE
  23. ).value(''.'', ''NVARCHAR(MAX)'')
  24. ,1,1,'''')'
  25.  
  26. EXECUTE sp_executeSql @query, N'@Comma_Delimited_String AS NVARCHAR(MAX) OUTPUT',@Comma_Delimited_String OUTPUT
  27. END
  28. GO
Source Code

 

运行示例,并得到结果:

 

  1. DECLARE @cols NVARCHAR(MAX)
  2. EXECUTE[dbo].[usp_DateColumnToCommaDelimitedString] #T,createdate,@cols OUTPUT
Source Code

 

再接下来,再参考另外一篇《动态为表添加存储时间字段https://www.cnblogs.com/insus/p/10943614.html

 

  1. EXECUTE [dbo].[usp_DyanmicallyAddStorageDatetimeField] 'tempdb','dbo','#TempRpt',@cols
  2.  
  3. EXECUTE('SELECT [caseno],[username],'+ @cols +' FROM #TempRpt')
Source Code

 

一切准备好,我们可以开始处理原始数据:

 

  1. DECLARE @r INT = 1,@rs INT = 0
  2. SELECT @rs = MAX([number]) FROM #T
  3. WHILE @r <= @rs
  4. BEGIN
  5. DECLARE @COLUMN_NAME SYSNAME,@createdate datetime,@username nvarchar(20),@caseno bigint
  6. SELECT @COLUMN_NAME = CONVERT(VARCHAR(30),[createdate], 23),@createdate = [createdate],@username = [username],@caseno = [caseno] FROM #T WHERE [number] = @r
  7.  
  8.  
  9. IF EXISTS(SELECT TOP 1 1 FROM #TempRpt WHERE [caseno] = @caseno)
  10. EXECUTE('UPDATE #TempRpt SET ['+ @COLUMN_NAME +'] = '''+ @createdate +''' WHERE [caseno] = '''+ @caseno +'''' )
  11. ELSE
  12. EXECUTE('INSERT INTO #TempRpt ([caseno],[username],['+ @COLUMN_NAME +']) VALUES('''+ @caseno +''',N'''+ @username +''','''+ @createdate +''')')
  13. SET @r = @r + 1
  14. END
  15.  
  16. EXECUTE('SELECT [caseno],[username],'+ @cols +' FROM #TempRpt')
Source Code

 

到此,应该已经可以结束了。达到想要的结果。

 

扩展,Insus.NET添加多笔不同username ,caseno数据行,
但同一username ,caseno记录中,有重复的记录

 

程序还是使用上面的程序,也均能得到预期的结果。

 

原文链接:http://www.cnblogs.com/insus/p/10944163.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号