我有许多设备在不同时间记录不同的数据,并希望在一个查询中获取所有数据,按时间排序。我所拥有的各种表格的一个例子:
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
有没有更简单的方法来编写这种查询?
答案 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
关键字。