2013-03-27 2 views
0

Я использую Postgres 9.1, и у меня есть запрос, который возвращает 2 столбца, которые я хотел бы воспроизвести, даже если данные отсутствуют. Важные части моего запроса являютсяОбъединить 2 таблицы, чтобы присоединиться к

SELECT DATE_TRUNC('week', tx_dttm) AS interval_time, institution_id FROM (...) 
WHERE institution_id IN (1, 3, 4, 5, 7, 9) GROUP BY interval_time, institution_id 

Это возвращает мне все институты и все interval_times так же, как я ожидал. Теперь мне также нужны строки, в которых нет данных. Я могу сделать следующее, чтобы получить либо по одному

SELECT DATE_TRUNC('week', tx_dttm) AS interval_time, institution_id FROM (...) 
WHERE institution_id IN (1, 3, 4, 5, 7, 9) GROUP BY interval_time, institution_id 
RIGHT JOIN generate_series('2012-02-03', '2013-02-18', interval '1 week') 
ON DATE_TRUNC('week', generate_series) = interval_time 

или

SELECT DATE_TRUNC('week', tx_dttm) AS interval_time, institution_id FROM (...) 
WHERE institution_id IN (1, 3, 4, 5, 7, 9) GROUP BY interval_time, institution_id 
RIGHT JOIN unnest(array[1, 3, 4, 5, 7, 9]) AS all_institution_id 
ON all_institution_id = institution_id 

однако, я хотел бы объединить их, так что я получаю все interval_times для всех учреждений. Похоже, что лучше всего создать некоторую промежуточную таблицу, которая содержит каждый экземпляр unit_id, который повторяется для каждого интервала_time, а затем RIGHT JOIN, но я не уверен, как это сделать. Любая помощь приветствуется.

EDIT

После игры вокруг немного, похоже, что я хочу сделать, состоит в следующем, но мой синтаксис является неправильным

SELECT DATE_TRUNC('week', tx_dttm) AS interval_time, institution_id FROM (...) 
WHERE institution_id IN (1, 3, 4, 5, 7, 9) GROUP BY interval_time, institution_id 
RIGHT JOIN unnest(array[1, 3, 4, 5, 7, 9]) AS all_institution_id, 
generate_series('2012-02-03', '2013-02-18', interval '1 week') 
ON DATE_TRUNC('week', generate_series) = dose_hsts.interval_time 
AND all_institution_id = institution_id 

ответ

0

Я думаю, что вы хотите UNION оба запроса. Попробуйте это:

SELECT DATE_TRUNC('week', tx_dttm) AS interval_time, institution_id FROM (...) 
WHERE institution_id IN (1, 3, 4, 5, 7, 9) GROUP BY interval_time, institution_id 
UNION 
SELECT DATE_TRUNC('week', tx_dttm) AS interval_time, institution_id FROM (...) 
WHERE institution_id IN (1, 3, 4, 5, 7, 9) GROUP BY interval_time, institution_id 
RIGHT JOIN generate_series('2012-02-03', '2013-02-18', interval '1 week') 
ON DATE_TRUNC('week', generate_series) = interval_time 
0

Я понял это, используя следующий синтаксис

SELECT DATE_TRUNC('week', tx_dttm) AS interval_time, institution_id FROM (...) 
WHERE institution_id IN (1, 3, 4, 5, 7, 9) GROUP BY interval_time, institution_id 
RIGHT JOIN (SELECT * FROM unnest(array[1, 3, 4, 5, 7, 9]) AS all_institution_id, 
generate_series('2012-02-03', '2013-02-18', interval '1 week')) 
ON DATE_TRUNC('week', generate_series) = dose_hsts.interval_time 
AND all_institution_id = institution_id 
1

Я думаю, что вы хотите CROSS JOIN, прежде чем делать LEFT JOIN (замена RIGHT JOIN на тот же эффект доступен здесь):

SELECT interval_time::date , institution_id, ... 
FROM generate_series(date_trunc('week', '2012-02-03'::date) 
             , '2013-02-18'::date 
        , interval '1 week') AS d(interval_time) 
CROSS JOIN unnest(array[1, 3, 4, 5, 7, 9]) AS i(institution_id) 
LEFT JOIN (
    SELECT date_trunc('week', tx_dttm) AS interval_time, institution_id 
    FROM ... 
    GROUP BY 1, 2 
    ) x USING (interval_time, institution_id); 
Смежные вопросы