Postgres-查询以从多个表中选择字段作为列

时间:2018-12-09 12:09:11

标签: sql postgresql join

我有下表

表1:产品

id  name  
1   Bread  
2   Bun  
3   Cake  

表2:费用项目

product| quantity  
1 |      100  
2 |      150  
3 |      180  
1 |      25  
2 |      30  

表3:收入项目

product| quantity  
1 |      100  
2 |      150  
3 |      180  
1 |      25  
2 |      30  

现在我想要这样的结果

product   |  sum of quantity of expenseitem | sum of quantity of income item  
1         |  125 |  125  
2         |  180 |  180  
3         |  180 |  180

要获取此结果的查询是什么?
谢谢

2 个答案:

答案 0 :(得分:2)

您可以尝试在具有聚合函数条件的子查询中使用UNION ALL

模式(PostgreSQL v9.6)

CREATE TABLE Product(
    id int,
    name varchar(50)
);


INSERT INTO Product VALUES (1,'Bread');  
INSERT INTO Product VALUES (2,'Bun');  
INSERT INTO Product VALUES (3,'Cake');  

CREATE TABLE ExpenseItems(
    product int,
    quantity int
);


INSERT INTO ExpenseItems VALUES (1,100);  
INSERT INTO ExpenseItems VALUES (2,150);  
INSERT INTO ExpenseItems VALUES (3,180);  
INSERT INTO ExpenseItems VALUES (1,25);  
INSERT INTO ExpenseItems VALUES (2,30);  


CREATE TABLE IncomeItems(
    product int,
    quantity int
);


INSERT INTO IncomeItems VALUES (1,100);  
INSERT INTO IncomeItems VALUES (2,150);  
INSERT INTO IncomeItems VALUES (3,180);  
INSERT INTO IncomeItems VALUES (1,25);  
INSERT INTO IncomeItems VALUES (2,30);  

查询#1

SELECT p.id,
      SUM(CASE WHEN grp = 1 THEN quantity END) SUMExpenseItems,
      SUM(CASE WHEN grp = 2 THEN quantity END) SUMIncomeItems
FROM (
    SELECT product, quantity,1 grp 
    FROM ExpenseItems
    UNION ALL
    SELECT product, quantity,2 
    FROM IncomeItems
) t1 JOIN Product p on p.id = t1.product
GROUP BY p.id;

| id  | sumexpenseitems | sumincomeitems |
| --- | --------------- | -------------- |
| 1   | 125             | 125            |
| 2   | 180             | 180            |
| 3   | 180             | 180            |

View on DB Fiddle

答案 1 :(得分:0)

与@ D-Shih的答案类似,PostgreSQL 9.4+支持FILTER()子句进行条件聚合,以代替CASE语句:

SELECT p.id,
       SUM(quantity) FILTER (WHERE grp = 1) SUMExpenseItems,
       SUM(quantity) FILTER (WHERE grp = 2) SUMIncomeItems
FROM 
     -- ...same union all query...
GROUP BY p.id