我如何加入这些表格?

时间:2011-12-19 06:50:09

标签: sql sql-server join

我有许多设备在不同时间记录不同的数据,并希望在一个查询中获取所有数据,按时间排序。我所拥有的各种表格的一个例子:

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
)

我希望在time_amps不匹配时,将一个查询连接到device_id上​​的表和包含空值的timestamp。我正在寻找的输出格式的一个例子是:

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语句的情况下执行timestamp列(请记住,虽然我只显示了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

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

4 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

是的,您可以使用OUTER Join到温度表。如果温度表中没有匹配的行,那将返回空值。

答案 2 :(得分: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而不是

答案 3 :(得分: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关键字。