Несколько операторов выбора в разных таблицах с разными ограничениями в одном запросе, результаты не отображаются как пустые - PullRequest
1 голос
/ 24 августа 2011

Я использую несколько запросов к нескольким таблицам, которые я хотел бы объединить в один запрос для эффективности и скорости.

Мои таблицы выглядят так:

m1
------------------------------------------------------------------------
id  |   time    |   min |   max     |   mean
------------------------------------------------------------------------
a       00:10:00    1       5       3
a       00:20:00    2       6       4
a       00:30:00    3       7       5
a       00:40:00    4       8       6
b       00:40:00    11      15      13
b       00:50:00    21      26      24
c       00:10:00    21      27      25

m2
------------------------------------------------------------------------
id  |   time    |   min |   max     |   mean
------------------------------------------------------------------------
a       00:30:00    22      44      33
a       00:40:00    33      55      44
a       00:50:00    44      66      55
b       00:20:00    1       4       2
b       00:30:00    1       3       2
b       00:30:00    2       5       4
c       00:20:00    6       7       6

m3
------------------------------------------------------------------------
id  |   time    |   min |   max     |   mean
------------------------------------------------------------------------
b       00:10:00    11      15      13
b       00:20:00    21      26      14
c       00:00:00    21      27      25

Мои запросы выглядят так:

SELECT min,max,mean FROM m1 WHERE id='a' AND time='00:10:00'
SELECT min,max,mean FROM m2 WHERE id='a' AND time='00:10:00'
SELECT min,max,mean FROM m3 WHERE id='a' AND time='00:10:00'
SELECT min,max,mean FROM m1 WHERE id='a' AND time='00:20:00'
SELECT min,max,mean FROM m2 WHERE id='a' AND time='00:20:00'
SELECT min,max,mean FROM m3 WHERE id='a' AND time='00:20:00'
SELECT min,max,mean FROM m1 WHERE id='a' AND time='00:30:00'
SELECT min,max,mean FROM m2 WHERE id='a' AND time='00:30:00'
SELECT min,max,mean FROM m3 WHERE id='a' AND time='00:30:00'
SELECT min,max,mean FROM m1 WHERE id='a' AND time='00:40:00'
SELECT min,max,mean FROM m2 WHERE id='a' AND time='00:40:00'
SELECT min,max,mean FROM m3 WHERE id='a' AND time='00:40:00'
SELECT min,max,mean FROM m1 WHERE id='a' AND time='00:50:00'
SELECT min,max,mean FROM m2 WHERE id='a' AND time='00:50:00'
SELECT min,max,mean FROM m3 WHERE id='a' AND time='00:50:00'

Я беру результаты этих запросов и вручную собираю их в массив, который выглядит следующим образом:

----------------------------------------------------------------------------------------------------------------------------------------------------------------
#|  time    |   m1.min  |   m1.max  |   m1.mean |   m2.min  |   m2.max  |   m2.mean |   m3.min  |   m3.max  |   m3.mean 
----------------------------------------------------------------------------------------------------------------------------------------------------------------
1   00:10:00    1           5           3           NULL        NULL        NULL        NULL        NULL        NULL
2   00:20:00    2           6           4           NULL        NULL        NULL        NULL        NULL        NULL
3   00:30:00    3           7           5           22          44          33          NULL        NULL        NULL
4   00:40:00    NULL        NULL        NULL        33          55          44          NULL        NULL        NULL
5   00:50:00    NULL        NULL        NULL        44          66          55          NULL        NULL        NULL

Я пытался выяснить, как сгенерировать вышеуказанный массив с помощью одного оператора SQL или одного оператора SQL на отметку времени. Я безуспешно пробовал объединения, союзы, заявления по делу и т. Д. Тот факт, что мне нужно отобразить «NULL» или иметь пустое значение в столбцах, где нет совпадающих результатов, - вот что, кажется, усложняет ситуацию.

Я использую PostgreSQL 8.3.6.

Любая помощь будет принята с благодарностью.

1 Ответ

2 голосов
/ 24 августа 2011

Самое близкое решение, которое я нашел, это использовать FULL OUTER JOIN так:

SELECT
    time,
    COALESCE(m1.min::text, 'NULL')  AS "m1.min",
    COALESCE(m1.max::text, 'NULL')  AS "m1.max",
    COALESCE(m1.mean::text, 'NULL') AS "m1.mean",
    COALESCE(m2.min::text, 'NULL')  AS "m2.min",
    COALESCE(m2.max::text, 'NULL')  AS "m2.max",
    COALESCE(m2.mean::text, 'NULL') AS "m2.mean",
    COALESCE(m3.min::text, 'NULL')  AS "m3.min",
    COALESCE(m3.max::text, 'NULL')  AS "m3.max",
    COALESCE(m3.mean::text, 'NULL') AS "m3.mean"
FROM
    (SELECT time, min, max, mean FROM m1 WHERE id = 'a') m1
    FULL JOIN
    (SELECT time, min, max, mean FROM m2 WHERE id = 'a') m2
    USING (time)
    FULL JOIN 
    (SELECT time, min, max, mean FROM m3 WHERE id = 'a') m3
    USING (time)
ORDER BY time;

Результат:

   time   | m1.min | m1.max | m1.mean | m2.min | m2.max | m2.mean | m3.min | m3.max | m3.mean 
----------+--------+--------+---------+--------+--------+---------+--------+--------+---------
 00:10:00 | 1      | 5      | 3       | NULL   | NULL   | NULL    | NULL   | NULL   | NULL
 00:20:00 | 2      | 6      | 4       | NULL   | NULL   | NULL    | NULL   | NULL   | NULL
 00:30:00 | 3      | 7      | 5       | 22     | 44     | 33      | NULL   | NULL   | NULL
 00:40:00 | 4      | 8      | 6       | 33     | 55     | 44      | NULL   | NULL   | NULL
 00:50:00 | NULL   | NULL   | NULL    | 44     | 66     | 55      | NULL   | NULL   | NULL
(5 rows)
...