棘手的 SQL SELECT 语句 - 将两行合并为两列

问题描述 投票:0回答:4

我的问题:
我有一个带有

Channel <int>
Value <float>
列的表,以及时间戳和其他几个包含附加数据的列。
Channel
1
2
,并且有 1 或 2 行除通道和值之外的所有内容都相同。

我想要做的是将这些数据选择到一个新表单中,其中两个通道显示为列。我尝试用

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'

更新以回应评论中提出的一些问题,以及一些后续问题/澄清:

  • 是的,正是

    Timestamp
    OtherStuff
    的组合将两行连接在一起。 (
    OtherStuff
    实际上不止一列,但为了简洁起见,我进行了简化。)还有一些其他列不一定相等,但应保持原样。

  • 所讨论的表已经由两个表连接而成,其中

    Value
    Channel
    Timestamp
    来自其中一个表,其余的(总共 7 列,其中 4 列始终等于“链接”行,而其他三行大多不是)。有一些使用
    INNER JOIN
    的建议 - 如果我已经将一些东西连接在一起,这些建议仍然有效吗(即使我没有
    myTable
    来连接自身)?

  • 很多的行具有相同的时间戳,因此我需要来自我要加入的两个表的信息来找出要链接在一起的行。

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

sql sql-server-2005 tsql group-by
4个回答
6
投票

只要你有链接两行的东西,就像这样

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

如果您没有任何东西链接两行,那么可能无法完成,因为您如何知道它们已配对?

如果您有 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                  

2
投票

类似...

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

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
也可以用在这里。


0
投票

我会按时间戳进行分组,因为其他值是相同的。

© www.soinside.com 2019 - 2024. All rights reserved.