Tricky SQL SELECT语句 - 将两行合并为两列

时间:2010-07-09 12:34:08

标签: sql sql-server-2005 tsql group-by

我的问题:
我有一个包含Channel <int>Value <float>列的表格,以及一个时间戳和其他一些包含其他数据的列。 Channel12,并且有1行或2行包含除channel和value之外的所有内容。

我想要做的是将这些数据选择为一个新表单,其中两个通道显示为列。我尝试使用GROUP BY做一些事情,但我无法弄清楚如何根据同一行上的频道将值输入正确的列。

示例:
对于那些相当关注我拥有的数据和我想要的数据并从那里想出来的人来说,就是这样。我有什么:

 Channel    Value       Timestamp                OtherStuff
 1          0.2394      2010-07-09 13:00:00      'some other stuff'
 2          1.2348      2010-07-09 13:00:00      'some other stuff'
 1          24.2348     2010-07-09 12:58:00      'some other stuff'
 2          16.3728     2010-07-09 12:58:00      'some other stuff'
 1          12.284      2010-07-09 13:00:00      'unrelated things'
 2          9.6147      2010-07-09 13:00:00      'unrelated things'

我想要的是什么:

Value1     Value2      Timestamp                OtherStuff
0.2394     1.2348      2010-07-09 13:00:00      'some other stuff'
24.2348    16.3728     2010-07-09 12:58:00      'some other stuff'
12.284     9.6147      2010-07-09 13:00:00      'unrelated things'

更新以回应评论中出现的一些问题,以及一些后续问题/说明:

  • 是的,TimestampOtherStuff的组合将两行链接在一起。 (OtherStuff实际上不止一列,但为了简洁,我简化了。)还有一些其他列不一定相同,但应该保持原样。

  • 有问题的表已经从两个表中加入,其中ValueChannelTimestamp来自其中一个表,其余表(共计7个表)列,其中4个对于“链接”行总是相等,而其他三个大多数不是)。使用INNER JOIN时有一些建议 - 如果我已经将各种东西加在一起(即使我没有myTable加入其自身),这些仍然有用吗?

  • 有很多行具有相同的时间戳,所以我需要来自我正在加入的两个表中的信息来确定要链接在一起的行。

    < / LI>
  • 我有很多数据。输入来自遍布全国的测量设备,其中大部分(如果不是全部)每2分钟上传一次测量(最多4个通道)。现在我们在线有大约1000台设备,所以这意味着每分钟平均增加大约1000行。我需要考虑至少3个,最好是6个小时的值,这意味着表中有180 000到360 000行,包括通道,值和时间戳。

3 个答案:

答案 0 :(得分:4)

只要你有一些链接2行的东西,就像这样

SELECT
    c1.Value AS Value1, c2.Value AS Value2, c1.timestamp, c2.otherstuff
FROM
    MyTable c1
    JOIN
    MyTable c2 ON c1.timestamp = c2.timestamp AND c1.otherstuff = c2.otherstuff
WHERE
    c1.Channel = 1 AND c2.Channel = 2

如果你没有任何链接2行的东西,那么它可能无法完成,因为你怎么知道它们是配对的?

如果你有1个 2行(编辑:并且不知道你有哪个频道值)

SELECT
    c1.Value AS Value1, c2.Value AS Value2, c1.timestamp, c2.otherstuff
FROM
    (
     SELECT Value, timestamp, otherstuff
     FROM MyTable
     WHERE Channel = 1
    ) c1           
    FULL OUTER JOIN
    (
     SELECT Value, timestamp, otherstuff
     FROM MyTable
     WHERE Channel = 2
    ) c2 ON c1.timestamp = c2.timestamp AND c1.otherstuff = c2.otherstuff                  

答案 1 :(得分:1)

像...一样的东西。

SELECT   MAX(CASE Channel WHEN 1 THEN Value ELSE 0 END) AS Value1,
         MAX(CASE Channel WHEN 2 THEN Value ELSE 0 END) AS Value2,
         Timestamp, 
         OtherStuff
FROM     {tablename}
GROUP BY Timestamp, OtherStuff

(我还没试过这个!) (这假设你的价值总是积极的!)

或者(见下面的评论)......

SELECT   SUM(CASE Channel WHEN 1 THEN Value ELSE 0 END) AS Value1, 
         SUM(CASE Channel WHEN 2 THEN Value ELSE 0 END) AS Value2, 
         Timestamp, 
         OtherStuff 
FROM     {tablename}
GROUP BY Timestamp, OtherStuff

答案 2 :(得分:0)

SELECT a.Value as Value1, b.Value as Value2,
a.TimeStamp, a.OtherStuff
FROM myTable a INNER JOIN myTable b
ON a.OtherStuff = b.OtherStuff and a.TimeStamp = b.TimeStamp
WHERE a.Channel = 1 AND b.Channel = 2

没有查询编辑器编写。请善待:)

编辑:INNER JOIN也可以在这里使用。 EDIT2:已更正为INNER JOIN。不要急于downvote:)