【问题标题】:How to transpose query result?如何转置查询结果?
【发布时间】:2021-07-21 10:21:15
【问题描述】:

我有如下简单的查询:

SELECT distinct DateTime , Result , count(Result)as total
  FROM [lfplog].[dbo].[d_lfpLog] group by datetime, result order by DateTime, result asc

从那个查询中,输出是这样的: DateTime 结果总计

**Date Time   Result      total**
2021-04-01  00000000    20
2021-04-01  00000028    10
2021-04-01  000000FF    9
2021-04-01  000001FF    2
2021-04-01  000004FF    58
2021-04-01  000005FF    4
2021-04-01  000006FF    4
2021-04-01  000007FB    3
2021-04-01  000007FF    467
2021-04-02  000000FF    2
2021-04-02  000004FF    1
2021-04-02  000007FF    13
2021-04-03  00000000    220
2021-04-03  00000028    16
2021-04-03  0000003F    1
2021-04-03  00000040    1
2021-04-03  000000FB    1
2021-04-03  000000FF    24
2021-04-03  00000100    3
2021-04-03  00000102    1
2021-04-03  000001FB    1
2021-04-03  000001FF    4
2021-04-03  000004FB    1
2021-04-03  000004FF    179
2021-04-03  00000500    1
2021-04-03  000005BB    1
2021-04-03  000005FB    2
2021-04-03  000005FF    15
2021-04-03  000006FF    8
2021-04-03  0000073F    50
2021-04-03  000007BA    2
2021-04-03  000007BF    2
2021-04-03  000007FA    1
2021-04-03  000007FB    22
2021-04-03  000007FF    1706
2021-04-04  00000000    2
2021-04-04  00000008    2
2021-04-04  00000010    12
2021-04-04  00000028    24
2021-04-04  0000003A    1
2021-04-04  0000003B    2
2021-04-04  0000003F    1
2021-04-04  00000068    1
2021-04-04  0000007B    1
2021-04-04  0000007F    1
2021-04-04  000000FB    1
2021-04-04  000000FF    26
2021-04-04  0000013F    1
2021-04-04  000001FF    3
2021-04-04  000004FB    1
2021-04-04  000004FF    77
2021-04-04  000005FF    14
2021-04-04  000006FF    4
2021-04-04  000007AB    1
2021-04-04  000007FB    31
2021-04-04  000007FF    1062

我正在寻找的是,如何将这些日期时间从行转换为列? 我的预期结果表是这样的:

             2021-04-01       2021-04-02        2021-04-03
00000000     20               34                35
00000000     10               65                76
00000028     9                7                 98
000000FF     2                8                 87
000001FF     58               9                 34
000004FF     343              23                98
000005FF     34               23                87
000006FF     23               3                 2

是否可以在 sql server 查询或过程中做到这一点? 或者我应该在后面的代码中处理它? (我正在使用 C#) 任何帮助将不胜感激 谢谢

【问题讨论】:

  • 日期是否总是与您在上面显示的三个日期完全相同?
  • 不,日期是每天的日期,所以每天数据都会自动插入到数据库中,我只需要每天按结果列汇总(计数)即可。是否可以在 sql server 查询中做到这一点?
  • 我不确定答案,但this 可能会有所帮助。
  • 根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。

标签: c# sql asp.net sql-server


【解决方案1】:

这里的区别是多余的

你可以在sql或者前端做; sql 已经知道如何做到这一点,而前端将需要一些编码来做到这一点,或者使用知道如何交叉表的报告库。在 sqls 中执行此操作会使结果稍微难以处理,因为列名每天都会更改,但如果您所做的只是向用户显示它,那么它的重要性就较小了。如果您正在使用一些面向对象的建模来处理它,那么您将无法轻松拥有与所有可用日期相关的属性名称的对象 - 使用这种形式的数据非常困难,映射到静态属性名称,您不会不要这样做,您只需将数据保留在数据表或类似文件中,然后调整代码逻辑以应对不同的列名

有几种常见的数据透视方法

SELECT *
FROM (select result, datetime from [lfplog].[dbo].[d_lfpLog]) a -- don't need a subquery if table only contains two columns
PIVOT (
  COUNT(*)
  FOR DateTime IN ([2021-04-01],[2021-04-02],[2021-04-03])
) x

你也可以有条件地聚合:

SELECT 
  Result ,
  SUM(CASE WHEN datetime = '2021-04-01' THEN 1 ELSE 0 END) as "2021-04-01",
  SUM(CASE WHEN datetime = '2021-04-02' THEN 1 ELSE 0 END) as "2021-04-02",
  SUM(CASE WHEN datetime = '2021-04-03' THEN 1 ELSE 0 END) as "2021-04-03"
FROM [lfplog].[dbo].[d_lfpLog] 
group by result 

您甚至可以将表格加入 3 次 on result = result and datetime = whatever

所有这些方法都需要您自己动态地形成查询(在 c# 中)。您不能告诉 sqlserver “透视此数据”并期望它会找到列本身 - 您必须明确列名。您要么必须以编程方式生成要输入的日期(使用字符串 concat;它不能被参数化),您必须运行查询以发现表中的日期并将它们连接到查询文本中

我的意思是你的代码必须是这样的:

DateTime d = new DateTime(2021,4,1);
string cols = string.Join(',', Enumerable.Range(0,3).Select(x => d.AddDays(x).ToString("[yyyy-MM-dd]"));
string sql = $@"SELECT *
FROM (select result, datetime from [lfplog].[dbo].[d_lfpLog]) a
PIVOT (
  COUNT(*)
  FOR DateTime IN ({cols})
) x";

【讨论】:

  • 感谢您的建议,我决定每天循环查询并显示在前端
【解决方案2】:

你可以使用 sql pivot 来获得你想要的结果

SELECT Result,   
'2021-04-01', ' 2021-04-02','2021-04-03'  
FROM  
(SELECT distinct DateTime , Result as total
  FROM [lfplog].[dbo].[d_lfpLog] group by datetime, result order by DateTime, result asc) AS SourceTable  
PIVOT  
(  
count(*)  
FOR DateTime IN ('2021-04-01', ' 2021-04-02','2021-04-03' )  
) AS PivotTable; 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 2015-01-30
    • 2019-12-29
    • 2021-10-30
    • 2011-07-23
    • 2017-03-02
    • 1970-01-01
    相关资源
    最近更新 更多