2015-07-20 85 views
3

我有兩個查詢從三個表拉:選擇另一列加入

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指着我在正確的方向:熱膨脹係數救援。

下面是測試查詢

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 
+1

你真的應該習慣了明確的'JOIN's而不是隱加入where子句中 –

回答

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 
+0

感謝您的答覆:無論是解決方案提供所需的結果:年份列出現在紅色和藍色兩者中能夠。使用任一響應(@vkp,@ImCrimson)會產生多個(重複)藍色記錄。重複次數等於紅色表中匹配的網站記錄的數量:使用原始示例,它將爲網站1生成三個記錄,紅色表中的每個值都會生成一個記錄。 – paddleman

+0

修改爲加入「年份」。試試這個 –

+0

感謝立即迴應:越來越近,但是這隻顯示紅色和藍色都有數據的年份的記錄;它不顯示記錄中不存在紅色記錄的藍色記錄(原始示例中的2011年和2008年)。 – paddleman

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' 
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)