在中间加入三个表与主表

时间:2018-04-17 08:40:19

标签: sql postgresql join

我正在加入三张桌子。我重新创建了一个简单的测试用例,我看到了同样的问题,所以看起来我在连接查询中犯了一个根本错误:

我有三张桌子:



case:
id (PK)| date_closed
155    | '2018-04-17 10:08' 
156    | '2018-03-17 10:08'     
pizza  | '2018-02-17 10:08' 

registration:
id (FK) | source | quantity
155     | market | 300
155     | sawdust| 200

bagged:
id | case_id (FK) | kg_bagged
X  | 155          | 123
Y  | 155          | 90




我想加入这些表来比较每个案例的总金额'在数量列和kg_bagged。因此案例表与其他两个有1:*的关系。因此,我创建了一个这样的连接查询:

SELECT case.id, 
       date_closed,
       SUM(quantity),
       SUM(kg_bagged),
       SUM(kg_bagged)/SUM(quantity) AS reduction_factor
FROM case
    JOIN bagged ON case.id = bagged.case_id
    JOIN registration ON case.id = registration.id

我认为这将是一个正确的查询,但Postgres告诉我,我必须将case.id,date_closed添加到group by子句中。所以我补充一点:

GROUP BY case.id, date_closed;

此代码正在运行且没有错误,但在情况155的情况下显示1000,而不是预期的500(200 + 300)。只有当记录超过1时才会出现此行为。当只将1个表连接到案例表时,它也可以正常工作。有人能看到JOIN查询中的错误吗?

我还尝试使用子查询连接两个表,而不是使用表左边的连接,但它给了我类似的结果

1 个答案:

答案 0 :(得分:1)

当您在其他2个表上连接数据2行时,它们匹配在一起,因此您得到相乘的结果。在你的例子中是2 * 2 = 4

为了便于理解,在您执行查询的情况下

 SELECT case.id, date_closed, source, quantity, kg_bagged
   FROM case
   JOIN registration ON registration.id = case.id
   JOIN bagged ON bagged.case_id = case.id

您将获得如下数据:

| id  | date_closed        | source | quantity | kg_bagged |
| :-: | :----------------: | :----: | :------: | :-------: |
| 155 | '2018-04-17 10:08' | market | 300      | 123       |
| 155 | '2018-04-17 10:08' | sawdust| 200      | 123       |
| 155 | '2018-04-17 10:08' | market | 300      | 90        |
| 155 | '2018-04-17 10:08' | sawdust| 200      | 90        |

在这种情况下,根据我之前的经验,我曾经先编写子查询,先获取总和数据,然后将它们连接在一起。

如:

   WITH r AS (SELECT id, sum(quantity) as quantity FROM registration GROUP BY id),
    b as (SELECT case_id, SUM(kg_bagged) as kg_bagged FROM bagged GROUP BY case_id)
 SELECT case.id, 
    date_closed,
    quantity,
    kg_bagged,
    kg_bagged/quantity AS reduction_factor
   FROM case
   JOIN b ON case.id = b.case_id
   JOIN r ON case.id = r.id

希望这个答案可以帮到你。