我从三个表中提取了两个问题:
t1 -sites
t2 - blues
t3 - reds
query1 -
SELECT s.site_name b.year b.value
FROM sites s, blues b
WHERE s.id = b.site_id AND s.site_name ='site1'
返回以下内容(例如)
| site_name | year | blues |
| site1 | 2012 | 23.6 |
| site1 | 2011 | 19.1 |
| site1 | 2010 | 10.2 |
| site1 | 2009 | 25.8 |
| site1 | 2008 | 14.0 |
查询2
SELECT s.site_name r.year r.value
FROM sites s, reds r
WHERE s.id = r.site_id
AND s.site_name ='site1'
返回:
| site_name | year | reds |
| site1 | 2012 | 14.0 |
| site1 | 2010 | 11.0 |
| site1 | 2009 | 18.9 |
我最终想要这个:
| site_name | year | blues | reds |
| site1 | 2012 | 23.6 | 14.0 |
| site1 | 2011 | 19.1 | |
| site1 | 2010 | 10.2 | 11.0 |
| site1 | 2009 | 25.8 | 18.9 |
| site1 | 2008 | 14.0 | |
这基本上相当于一个网站的蓝调和红色表中的所有记录,即使其中一个表没有该年的记录,也会与年份相匹配。
非常感谢@vkp指出我正确的方向:CTE救援。
以下是经过测试的查询
WITH x AS (SELECT s.site_name AS name, b.year AS yr1, b.value AS blue_val
FROM public.sites s JOIN public.blues b
ON s.id = b.site_id
WHERE s.site_name = 'Site1'
), y AS (SELECT s.site_name, r.year AS yr2, r.value AS red_val
FROM public.stations s JOIN public.reds r
ON s.id = r.site_id
WHERE s.site_name = 'Site1'
)
SELECT x.name, x.yr1, x.blue_val, y.red_val
FROM x LEFT JOIN y ON x.yr1 = y.yr2
答案 0 :(得分:2)
SELECT s.site_name, b.year, b.value as blues, r.value as reds
FROM sites s right join blues b on s.id = b.site_id
right join reds r on s.id = r.site_id and b.year = r.year
where s.site_name ='site1'
使用CTE更新了查询:
with x as (SELECT s.site_name, b.year, b.value as blues
FROM sites s join blues b on s.id = b.site_id
where s.site_name ='site1')
, y as (SELECT s.site_name, r.year, r.value as blues
FROM sites s join reds r on s.id = r.site_id
where s.site_name ='site1')
,yrs as (select year from x union select year from y)
select
case when x.site_name is not null then x.site_name
else y.site_name end as site_name
, yrs.year, x.value as blue_val, y.value as red_val
from yrs left join x on x.year = yrs.year
left join y on y.year = yrs.year
答案 1 :(得分:0)
SELECT s.site_name b.year b.value r.value
FROM sites s
INNER JOIN blues b ON s.id = b.site_id AND s.site_name ='site1'
INNER JOIN reds r ON s.id = r.site_id AND s.site_name ='site1'
答案 2 :(得分:0)
如果语法不正确,请原谅我 - 我对Postgresql并不熟悉。
如果您可以嵌套查询:
SELECT
s.site_name,
i.year,
i.blues,
i.reds
FROM
#sites AS s,
(
SELECT
COALESCE( b.site_id, r.site_id ) AS site_id,
COALESCE( b.year, r.year ) AS year,
b.value AS blues,
r.value AS reds
FROM
#blues AS b
FULL OUTER JOIN #reds AS r
ON r.year = b.year AND r.site_id = b.site_id
) AS i
WHERE
s.site_name = 'site1' AND
i.site_id = s.site_id
如果不能,请使用UNION分隔您在年内同时存在蓝色和红色的集合的连接类型,其中年份仅存在蓝色且仅存在红色这一年:
SELECT
s.site_id,
b.year AS year,
b.value AS blues,
r.value AS reds
FROM
#sites s
INNER JOIN #blues b
ON b.site_id = s.site_id
INNER JOIN #reds r
ON r.site_id = s.site_id AND
r.year = b.year
WHERE
s.site_name = 'site1'
UNION
SELECT
s.site_id,
b.year AS year,
b.value AS blues,
null AS reds
FROM
#sites s
INNER JOIN #blues b
ON b.site_id = s.site_id
WHERE
s.site_name = 'site1' AND
b.year NOT IN ( SELECT year FROM #reds WHERE #reds.site_id = s.site_id )
UNION
SELECT
s.site_id,
r.year AS year,
null AS blues,
r.value AS reds
FROM
#sites s
INNER JOIN #reds r
ON r.site_id = s.site_id
WHERE
s.site_name = 'site1' AND
r.year NOT IN ( SELECT year FROM #blues WHERE #blues.site_id = s.site_id )