Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何为透视聚合指定分组依据_Sql_Sql Server_Tsql_Pivot - Fatal编程技术网

Sql 如何为透视聚合指定分组依据

Sql 如何为透视聚合指定分组依据,sql,sql-server,tsql,pivot,Sql,Sql Server,Tsql,Pivot,或者也许有另一种选择。问题其实很简单: 我有以下信息(更多行数为30万行): 这是一个称为“CTE_dl2”的CTE 我以这种方式旋转数据: SELECT * FROM ( SELECT * FROM cte_dl2 ) Temp PIVOT ( MAX(StartOrEnd) FOR StartTimeEndTime IN ([StartTime], [EndTime]) ) Pvt 这让我感到: MachID DownCode

或者也许有另一种选择。问题其实很简单:

我有以下信息(更多行数为30万行):

这是一个称为“CTE_dl2”的CTE

我以这种方式旋转数据:

SELECT * FROM
(
    SELECT *
    FROM cte_dl2
) Temp
PIVOT
(
    MAX(StartOrEnd)
    FOR StartTimeEndTime IN ([StartTime], [EndTime])
) Pvt
这让我感到:

MachID  DownCode                StartTime   EndTime
------------------------------------------------------
PR01    ColorChg                1375207208  1375207316
PR01    COMP                    1412124847  1412131608
PR01    DIE SET                 1408502593  1408502595
PR01    DieStart                1397704258  1397704381
PR01    FeedLoad                1375099369  1375099506
...
您可以在这里看到问题:它会自动对in()的
透视中未指定的所有列执行
分组,因此我只获取每个
MachID
/
DownCode
的最新
开始时间和
结束时间

如果你看不出问题所在,以下是我想要了解的:

MachID  DownCode                StartTime   EndTime
------------------------------------------------------------
PR01    ColorChg                1337713300  1337713303
PR01    ColorChg                1363254067  1363254075
PR01    ColorChg                1363259848  1363260292
...
请帮忙!我已经有办法解决这个问题,但它们没有
UNPIVOT
那么快:

  • 我的路线(未显示)=6s
  • UNPIVOT=3s
因此,我想继续使用
UNPIVOT
或等效工具

行的顺序在下面的注释中指定


为了向任何有类似问题的人澄清,答案是创建一列,其中每一行都有一个唯一的值,因为
PIVOT
总是在非PIVOT列上执行隐式
groupby

只要有一列是完全唯一的,这个隐式的
groupby
基本上没有效果


注意:我实际上还没有查看执行计划,以查看
PIVOT
是否正是以这种方式工作的,但从抽象上看,它似乎是,这就是为什么选择的答案是有效的。

不清楚您如何将
开始时间
结束时间
相互关联,但是您应该能够使用
行数()
返回多行
MachId
下代码
的组合。这将创建另一列,该列的唯一性足以在最终选择中返回多行:

select machid,
  downcode,
  StartTime, 
  EndTime
from
(
  select machid,
    downcode,
    startorend,
    starttimeendtime,
    rn = row_number() over(partition by machid, downcode, StartTimeEndTime
                            order by startorend) 
  from cte_dl2
) d
pivot
(
  max(startorend)
  for starttimeendtime in (StartTime, EndTime)
) piv;
注意,这假设您希望
开始时间
结束时间
基于
StartOrEnd
值,但是表中的数据并不是天生有序的-如果您有一列可以用来按特定顺序放置数据,那么获得正确的顺序会容易得多

如果您不想使用
PIVOT
这可以通过使用聚合函数和
CASE
表达式来实现:

select 
  machid,
  downcode,
  StartTime = max(case when starttimeendtime = 'StartTime' then startorend else null end),
  EndTime = max(case when starttimeendtime = 'EndTime' then startorend else null end) 
from
(
  select machid,
    downcode,
    startorend,
    starttimeendtime,
    rn = row_number() over(partition by machid, downcode, StartTimeEndTime
                            order by startorend) 
  from cte_dl2
) d
group by machid, downcode, rn;
看。您将在以下任一版本中获得相同的结果:

| MACHID | DOWNCODE |  STARTTIME |    ENDTIME |
|--------|----------|------------|------------|
|   PR01 | ColorChg | 1337713300 | 1337713303 |
|   PR01 | ColorChg | 1363254067 | 1363254075 |
|   PR01 | ColorChg | 1363259848 | 1363260292 |

你怎么知道哪个
EndTime
对应哪个
StartTime
?如果它是由MachID、DownCode和StartOrEnd排序的,那么它总是下一个。是什么使一行成为“下一个”?表中没有自然顺序,有没有一个专栏我们可以用来排序结果?我讨厌粗鲁,但我只是说如果是MachID、DownCode、
StartOrEnd的
排序
ed
。一点也不粗鲁,我想念你的那部分comment@KthProg好的,如果你觉得有必要继续讨论CAP与非CAP的区别,那就去聊天吧。这是一个离题的问题。@bluefeet不,我想我们基本上已经解决了(尽管事实上,人们有他们自己的风格)。如果有这么多人坚持这种风格,那么可能
CAPS
风格没有我想象中的好处,这两种方式都不会困扰我。@KthProg“不太管用”的意思是什么?小提琴中的结果正是你想要的结果。@Lamak
-
我的错,我只是没有对结果进行排序,所以它看起来没有正常工作。它确实起了作用,非常感谢。我删除了评论。
| MACHID | DOWNCODE |  STARTTIME |    ENDTIME |
|--------|----------|------------|------------|
|   PR01 | ColorChg | 1337713300 | 1337713303 |
|   PR01 | ColorChg | 1363254067 | 1363254075 |
|   PR01 | ColorChg | 1363259848 | 1363260292 |