2010-07-09 47 views
2

我的问题:
我有一个Channel <int>表和Value <float>柱,用时间戳和与附加数据的其他几个栏目的沿。 Channel要么是1要么是2,并且有1或2行除了通道和值都相同外,其他都有。整蛊SQL SELECT语句 - 将两个排为两列

我想要做的是将这些数据选择到一个新的窗体中,其中两个通道显示为列。我试图用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' 

更新响应已在评论arised一些问题,以及一些后续的问题/澄清:

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

  • 所讨论的表已经从两个表,其中ValueChannelTimestamp来自它们中的一个接合,其余的(共7个柱,出其中4总是相等为“链接”行,其他三个大多不是)。有几个建议使用INNER JOIN - 如果我已经加入了东西(即使我没有myTable加入自己),这些建议是否仍然有效?

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

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

+0

什么链接2行?时间戳和其他东西? – gbn 2010-07-09 12:38:02

+0

刚刚问了一个问题,就是这个:)! – Baaju 2010-07-09 13:32:05

回答

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     
+0

我确实有1 *或* 2行。即使我不知道如果我只有一行,我也不知道哪一个频道,第二种方法会如何? – 2010-07-09 13:07:34

+0

@tomas lycken:我已经更新了这个案例 – gbn 2010-07-09 13:10:50

+0

恐怕我过度简化了我的表结构 - 请参阅我的问题的更新。我是否应该通过首先连接到表变量来解决两个连接表的事实,或者是否有一种很好的方法来实现这一点,即使并非所有的列都来自同一个表?我想我可以加入另一张桌子,但我应该在哪里做到这一点以获得最佳表现? (该查询已经花了差不多一分钟的时间......) – 2010-07-09 13:56:17

-1
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也可以在这里使用。 编辑2:更正了INNER JOIN。不要急于downvote :)

+0

-1没有使用JOIN。其他开发人员很难看到语法FROM table1,table2发生了什么。 – JonH 2010-07-09 12:41:37

+0

无论如何也是错误的形式。 “a.TimeStamp = 1 AND b.TimeStamp = 2”? – gbn 2010-07-09 12:42:29

+0

@gbn:是的。我已纠正它。感谢SO,这里有一个编辑功能(想象一下否则就会降价)。 – shahkalpesh 2010-07-09 12:44:51

0

喜欢的东西...

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

不幸的是,我不能认为价值总是正面的。但是,无论如何谢谢=) – 2010-07-09 13:05:48

+0

好吧,以及如果总是只有1行的通道1和正好1行的通道2(每个时间戳),那么看看我的替代方案(上面) – barrylloyd 2010-07-09 13:28:41

+0

不幸的是,情况并非如此 - 我需要* *时间戳和其他东西(几列)来区分。正如你在我的例子中看到的那样,通道1和时间戳13:00可能有两行不属于同一个“链接”行。 – 2010-07-09 13:41:53