2011-11-08 58 views
1

我該如何使用連接編寫此查詢?我試圖去做,但它不起作用。PostgreSQL:如何使用連接編寫查詢?

select fund.fundname, sum(shares) as tt, (sum(shares)*price.price) as value 
from trans, fund, customer, price 
where trans.fundid = fund.fundid 
and trans.transdate = '2009-1-1' 
and price.fundid = trans.fundid 
and price.pricedate = trans.transdate 
and trans.sin = customer.sin 
and customer.name = 'Jacob' 
group by fund.fundname, price.price; 

感謝

+1

這是連接,甚至三個。可能甚至是交叉連接。你有什麼嘗試,爲什麼沒有工作?錯誤訊息? – stefan

回答

1

我想你在談論明確連接。就像你所擁有的那樣,連接只是隱含的。你會做這樣的:

SELECT fund.fundname, sum(shares) as tt, (sum(shares)*price.price) as value 
FROM trans 
JOIN fund 
ON (trans.fundid = fund.fundid) 
JOIN customer 
ON (trans.sin = customer.sin) 
JOIN price 
ON (price.fundid = trans.fundid) 
WHERE trans.transdate = '2009-1-1' 
AND price.pricedate = trans.transdate 
AND customer.name = 'Jacob' 
GROUP BY fund.fundname, price.price; 

PostgreSQL的還允許USING一個漂亮的簡寫,這將只包括在最終的結果集中列的一個副本:

SELECT fundname, sum(shares) as tt, (sum(shares)*price.price) as value 
FROM trans 
JOIN fund 
USING (fundid) 
JOIN customer 
USING (sin) 
JOIN price 
USING (fundid) 
WHERE trans.transdate = '2009-1-1' 
AND price.pricedate = trans.transdate 
AND customer.name = 'Jacob' 
GROUP BY fund.fundname, price.price; 
+0

謝謝..我試圖對它進行自然連接。常規連接和自然連接有區別嗎?我的語法錯了,我相信...... –

+2

'NATURAL' JOINS將加入每個相似命名的列。 –

+1

天然連接沒有什麼自然的。 – stefan

1

你一定要分開連接條件和篩選條件:

SELECT fund.fundname, SUM(shares) AS tt, SUM(shares) * price.price AS value 
FROM trans 
INNER JOIN fund 
    USING (fundid) 
INNER JOIN price 
    ON price.fundid = trans.fundid 
    AND price.pricedate = trans.transdate 
INNER JOIN customer 
    USING (sin) 
WHERE transdate = '2009-1-1' 
    AND customer.name = 'Jacob' 
GROUP BY fund.fundname, price.price 

請注意,USING會「合併」兩列,因此您不必使用別名。

1
select fund.fundname, sum(shares) as tt, (sum(shares)*price.price) as value 
from trans 
join fund on fund.fundid=trans.fundid 
join customer on customer.sin=trans.sin 
join price on price.pricedate=trans.transdate 
where 
trans.transdate = '2009-1-1' 
and customer.name = 'Jacob' 
group by fund.fundname, price.price; 
1

還有一個:

SELECT f.fundname 
     ,sum(shares) AS tt 
     ,(sum(shares) * p.price) AS value 
FROM trans t 
JOIN fund f USING (fundid) 
JOIN price p ON (p.fundid, p.pricedate) = (t.fundid, t.transdate) 
JOIN customer c USING (sin) 
WHERE t.transdate = '2009-1-1' 
AND c.name = 'Jacob' 
GROUP BY 1, p.price; 

我使用了一些語法簡化:

  • USING如果左,右功能相同的名稱。小心,如果該名稱彈出多次,那麼JOINS的順序會有所不同,或者它可能會變得模糊不清。示例:sin。如果還有fund.sin,則必須改爲使用顯式JOIN ON

  • (p.fundid, p.pricedate) = (t.fundid, t.transdate)是短期的
    (p.fundid = t.fundid AND p.pricedate = t.transdate)

  • GROUP BY 1 IST簡稱
    GROUP BY <fist column in the select list>

更多有關fine manual here連接。