【问题标题】:Postgres join and count multiple relational tablesPostgres 连接并计算多个关系表
【发布时间】:2020-09-30 13:26:47
【问题描述】:

我想将 2 个表连接到第一个表并按供应商名称分组。我在下面列出了三个表。

Vendors Table

| id         |      name 
|:-----------|------------:|
| test-id    | Vendor Name |    

VendorOrders Table

| id         | VendorId    | Details      | isActive(Boolean)| price |
|:-----------|------------:|:------------:| -----------------| --------
| random-id  |   test-id   |  Sample test |   TRUE            | 5000

OrdersIssues Table

| id         | VendorOrderId| Details.   |
|:-----------|--------------:-----------:|
| order-id   |   random-id  | Sample test|   

预期的输出是统计有多少订单属于一个供应商,有多少问题属于一个供应商订单。

我有下面的代码,但它没有给出正确的输出。

SELECT "vendors"."name" as "vendorName", 
COUNT("vendorOrders".id) as allOrders,
COUNT("orderIssues".id) as allIssues 
FROM "vendors" 
LEFT OUTER JOIN "vendorOrders" ON "vendors".id = "vendorOrders"."vendorId" 
LEFT OUTER JOIN "orderIssues" ON "orderIssues"."vendorOrderId" = "vendorOrders"."id"
GROUP BY "vendors".id;```

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    您需要关键字DISTINCT,至少对于allOrders

    SELECT v.name vendorName, 
           COUNT(DISTINCT vo.id) allOrders,
           COUNT(DISTINCT oi.id) allIssues 
    FROM vendors v
    LEFT OUTER JOIN vendorOrders vo ON v.id = vo.vendorId 
    LEFT OUTER JOIN orderIssues oi ON oi.vendorOrderId = vo.id
    GROUP BY v.id, v.name;
    

    考虑使用别名而不是完整的表名,以使代码更短且更具可读性。

    【讨论】:

    • 感谢您的回复,知道如何计算 isActive=true 的订单以使用别名“activeOrders”吗?
    • @dealwap 试试:COUNT(DISTINCT CASE WHEN vo.isActive THEN vo.id END) activeOrders.
    • 在同一张表上,如果我需要总结一个price 列怎么办?请注意,我不能使用 DISTINCT,因为不同的表可能具有相同的值。有什么想法吗?
    • 在具有多个连接的查询中,结果可能包含您想要求和的价格的重复行。所以只是 SUM(price) 可能会返回错误的结果。发布带有示例数据和预期结果的问题,以阐明您想要什么。
    【解决方案2】:

    您正沿着两个相关维度加入。总行数是问题的数量。但是要获得订单数量,您需要一个不同的计数:

    SELECT v.*, count(distinct vo.id) as num_orders,
           COUNT(oi.vendororderid) as num_issues
    FROM vendors v LEFT JOIN
         vendorOrders vo
         ON v.id = vo.vendorId LEFT JOIN
         orderIssues oi
         ON oi.vendorOrderId = vo.id
    GROUP BY v.id;
    

    注意事项:

    • 表别名使查询更易于编写和阅读。
    • 引用列名和表名会使查询更难读写。不要引用标识符(您可能需要重新创建表)。
    • Postgres 支持SELECT v.* . . . GROUP BY v.id 假设id 是主键(实际上只需要唯一)。这似乎是一个合理的假设。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      • 2019-05-03
      • 2019-08-22
      • 1970-01-01
      • 1970-01-01
      • 2015-03-22
      相关资源
      最近更新 更多