合并2个表加入

时间:2013-03-27 15:48:16

标签: sql postgresql left-join cross-join generate-series

我正在使用Postgres 9.1,我有一个查询返回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。看起来最好的做法是创建某种中间表,其中包含每个interval_time重复的每个institution_id,然后对此进行RIGHT JOIN,但我不知道该怎么做。任何帮助将不胜感激。

修改

玩了一下之后,看起来我想做的就是以下内容,但我的语法错了

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

3 个答案:

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

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

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