2011-11-08 34 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连接。