【问题标题】:SQL get table1 names with a count of table2 and table3SQL 获取 table1 名称,其中包含 table2 和 table3 的计数
【发布时间】:2022-12-18 08:25:22
【问题描述】:

我有三张表,table1和table2和table3相连,但是table2和table3没有相连。我需要每个 table1 行的 table2 和 table3 的输出计数。我必须使用 joins 和 group by table1.name

SELECT Tb_Product.Name, count(TB_Offers.Prod_ID) 'Number of Offers', count(Tb_Requests.Prod_ID) 'Number of Requests'
FROM Tb_Product LEFT OUTER JOIN
                         Tb_Requests ON Tb_Product.Prod_ID = Tb_Requests.Prod_ID LEFT OUTER JOIN
                         TB_Offers ON Tb_Product.Prod_ID = TB_Offers.Prod_ID
GROUP BY Tb_Product.Name

我需要结合这些查询:

SELECT Tb_Product.[Name], count(TB_Offers.Prod_ID) 'Number of Offers'
FROM Tb_Product  LEFT OUTER JOIN
                         TB_Offers ON Tb_Product.Prod_ID = TB_Offers.Prod_ID
GROUP BY Tb_Product.[Name]

SELECT Tb_Product.[Name], count(Tb_Requests.Prod_ID) 'Number of Requests'
FROM Tb_Product LEFT OUTER JOIN
                         Tb_Requests ON Tb_Product.Prod_ID = Tb_Requests.Prod_ID
GROUP BY Tb_Product.[Name]

结果:

Name    Number of Offers
Airplane    6
Auto    5
Bike    3
Camera  0
Computer    12
Milk    4
Oil 4
Orange  6
Telephone   0
Truck   6
TV  4
Name    Number of Requests
Airplane    1
Auto    5
Bike    0
Camera  2
Computer    6
Milk    4
Oil 5
Orange  6
Telephone   0
Truck   1
TV  5

我的报价和请求结果是相同的值。我不确定我在连接上做错了什么。我是否需要以某种方式将产品加入请求并单独将产品加入报价?这需要在一个查询中完成。

这是一个类。解释也将不胜感激。

【问题讨论】:

  • 我建议使用相关子查询来计数而不是外部连接。
  • 这是因为连接的工作方式。将 Product 连接到 Requests 会产生一个新关系,然后将该关系连接到 Offers 会产生最终关系。然后,您只需计算来自相同关系的两列中的值,因此计算相同的行数。

标签: sql


【解决方案1】:

听起来您的查询很接近,但您需要使用 GROUP BY 来确保每个产品都有自己的报价和请求计数。

以下是您可能如何编写查询的示例:

SELECT Tb_Product.Name, count(TB_Offers.Prod_ID) as 'Number of Offers', count(Tb_Requests.Prod_ID) as 'Number of Requests'
FROM Tb_Product
LEFT OUTER JOIN Tb_Requests ON Tb_Product.Prod_ID = Tb_Requests.Prod_ID
LEFT OUTER JOIN TB_Offers ON Tb_Product.Prod_ID = TB_Offers.Prod_ID
GROUP BY Tb_Product.Name

在此查询中,我们使用 LEFT OUTER JOIN 将 Tb_Product 表与 Tb_Requests 和 TB_Offers 表合并。这使我们能够在最终结果中包含可能没有任何报价或要求的产品。

然后我们使用 GROUP BY 按 Tb_Product.Name 对结果进行分组,这确保每个产品都有自己的报价和请求计数。这是必要的,因为如果没有 GROUP BY,报价和请求的计数将计算所有产品,从而导致每个产品的值相同。

【讨论】:

  • OP 确实有一个 GROUP BY,这不会解决问题
  • 谢谢,是的,我正在使用 group by,我添加了两个查询,我只需要将它们组合起来。我不确定如何在一个查询中准确地做到这一点
【解决方案2】:

最简单的方法是计算清楚的每列的值:

SELECT 
    Tb_Product.Name, 
    count(distinct TB_Offers.Prod_ID) 'Number of Offers', 
    count(distinct Tb_Requests.Prod_ID) 'Number of Requests'
FROM 
    Tb_Product 
    LEFT OUTER JOIN
    Tb_Requests ON Tb_Product.Prod_ID = Tb_Requests.Prod_ID 
    LEFT OUTER JOIN
    TB_Offers ON Tb_Product.Prod_ID = TB_Offers.Prod_ID
GROUP BY 
    Tb_Product.Name

这是必要的,因为联接连续工作以生成作为所有输入关系组合的行集的方式。 COUNT() 通常对列中的非空值进行计数。

您也可以这样做,它独立地聚合子表的计数,然后将它们连接到基表:

SELECT
    p.Name,
    o.cnt as Offer_Count,
    r.cnt as Request_Count
FROM 
    TB_Product p
    LEFT OUTER JOIN 
    (SELECT Prod_ID, COUNT(1) cnt FROM TB_Offers GROUP BY Prod_ID) o 
    LEFT OUTER JOIN 
    (SELECT Prod_ID, COUNT(1) cnt FROM TB_Requests GROUP BY Prod_ID) r 

更多解释...

假设您有两种产品:

Prod_ID Name
1 Widget
2 Gizmo

还有两个报价,每个产品一个:

Offer_ID Prod_ID
100 1
200 2

每个产品有两个请求:

Request_ID Prod_ID
1001 1
1002 1
2001 2
2002 2

现在你在 Prod_ID 上加入 Product 关系到 Offer 关系,你会得到这样的结果:

Prod_ID Name Offer_ID Prod_ID
1 Widget 100 1
2 Gizmo 200 2

现在,当您在 Prod_ID 上加入与 Requests 的关系时,您会得到如下内容:

Prod_ID Name Offer_ID Prod_ID Request_ID Prod_ID
1 Widget 100 1 1001 1
1 Widget 100 1 1002 1
2 Gizmo 200 2 2001 2
2 Gizmo 200 2 2002 2

现在,当您计算这些列中的任何一列时,您会得到 4,因为每列都有 4 个值。

【讨论】:

  • 谢谢你。当我运行第一个时,我得到 1 或 0 的计数,我相信使用不同的值消除了我需要计算的结果,即使它们是相同的。你的解释很有帮助。我会继续努力。再次感谢你!
猜你喜欢
  • 2017-11-15
  • 2017-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
相关资源
最近更新 更多