PostgreSQL:如何使用连接编写查询?

时间:2011-11-08 23:56:31

标签: sql postgresql join

如何使用连接编写此查询?我试过这样做但它不起作用。

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;

由于

4 个答案:

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

答案 1 :(得分: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将“合并”两列,因此您不必使用别名。

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

答案 3 :(得分: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 1GROUP BY <fist column in the select list>

有关fine manual here中加入的详情。