2011-12-19 154 views
0

我有许多设备在不同的时间记录不同的数据,并希望在一次查询中获取所有数据,并按时间排序。种表的一个例子,我有:我如何加入这些表格?

CREATE TABLE location(
    device_id INT, -- REFERENCES device(id) 
    timestamp DATETIME2 NOT NULL, 
    position GEOMETRY NOT NULL 
) 

CREATE TABLE temperature(
    device_id INT, -- REFERENCES device(id) 
    timestamp DATETIME2 NOT NULL, 
    temp FLOAT NOT NULL 
) 

我想有加入包含空值时的时间戳不匹配的DEVICE_ID和时间戳的表的单个查询。我要求的输出格式的一个例子是:

device_id, timestamp, location, temperature 
1, 2011/12/1 10:00:00, (35.1, 139.2), NULL 
1, 2011/12/1 10:00:01, NULL, 9.0 
1, 2011/12/1 10:00:02, (35.1, 139.2), 9.1 

我试着做FULL JOIN,但无法弄清楚如何做时间戳列没有一个巨大的CASE语句(记住,虽然我只出2个表格,这可以有更多)。

SELECT 
    location.device_id, 
    CASE WHEN location.timestamp IS NOT NULL THEN 
     location.timestamp 
    ELSE 
     temperature.timestamp 
    END as timestamp, 
    location, 
    temp 
FROM 
    location 
    FULL JOIN temperature ON location.device_id = temperature.device_id 
     AND location.timestamp = temperature.timestamp 
ORDER BY 
    timestamp 

有没有更简单的方法来写这种查询?

回答

5

您可以使用COALESCE表达式。

SELECT 
    location.device_id, 
    COALESCE(location.timestamp, temperature.timestamp) as timestamp, 
    position, 
    temp 
FROM 
    location 
    FULL JOIN temperature ON location.device_id = temperature.device_id 
     AND location.timestamp = temperature.timestamp 
ORDER BY 
    timestamp; 
+0

使用coalesce操作符完成这项工作。 isnull()运算符将执行相同的操作,但只接受2个参数,而合并接受许多参数。 – AndrewBay 2011-12-19 07:00:08

+0

工程就像一个魅力!非常感谢! – brianestey 2011-12-19 07:44:01

0

是的,你可以使用一个外部加入温度表。在温度表中没有匹配的行的情况下,这将返回空值。

0

你需要一个COALESCE得到DEVICE_ID /时间戳,内容如下:

SELECT 
    COALESCE(l.device_id, t.device_id) as device_id, 
    COALESCE(l.timestamp, t.timestamp) as timestamp, 
    l.position as location, 
    t.temp as temperature 
FROM location l 
FULL JOIN temperature t ON l.device_id = t.device_id 
    AND l.timestamp = t.timestamp 
ORDER BY 2 

用非常短的名称(L和T)走样表还要注意增加可读性。

您可以查看您的订购 - 也许你想ORDER BY 1, 2代替

0
SELECT device_id, timestamp, position, NULL AS temp 
    FROM location 
UNION ALL 
SELECT device_id, timestamp, NULL AS position, temp 
    FROM temperature 
ORDER 
    BY timestamp; 

注意这里需要的ALL关键字。