Как я могу присоединиться к этим столам? - PullRequest
0 голосов
/ 19 декабря 2011

У меня есть несколько устройств, которые регистрируют разные данные в разное время и хотят получить все данные в одном запросе, упорядоченные по времени. Пример видов таблиц, которые у меня есть:

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

Есть ли более простой способ написать запрос такого типа?

Ответы [ 4 ]

5 голосов
/ 19 декабря 2011

Вы можете использовать выражение 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 голосов
/ 19 декабря 2011
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.

0 голосов
/ 19 декабря 2011

Вам нужно COALESCE, чтобы получить device_id / timestamp, как показано ниже:

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 голосов
/ 19 декабря 2011

Да, вы можете использовать OUTER Join к таблице температур.Это вернет нули в случае, если в таблице температур нет подходящей строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...