【问题标题】:SQL Query With Count And Joining Table带有计数和连接表的 SQL 查询
【发布时间】:2018-11-14 06:56:28
【问题描述】:

我有以下三个表:

客户
身份证 (PK)
名字

产品
身份(PK)
名称
价格

交易
身份(PK)
customer_id(FK ref Customer.id)
product_id(FK ref Product.id)
创建日期

我正在运行以下查询,它提供了每位客户使用的产品数量:

SELECT p.id, p.name, Count(p.id), p.price
FROM transaction t, product p, customer c
WHERE p.id = t.product_id
      AND  c.id = t.customer_id
      AND c.id = 1
group by p.price, p.name, p.id
ORDER BY p.name ASC;

这可行,只是它只给我客户使用过的产品及其各自的数量。我想要的是客户未使用的那些产品的计数为 0 的所有产品的列表。我很难弄清楚这一点,因为我使用 Transaction 表作为客户和产品之间的连接表,并且我找到每个客户每个产品的计数的方式是通过记录计数(如您在上面的 SQL 代码中所见)。

我能做到:

SELECT *
FROM product
WHERE product.name NOT IN (SELECT p.name
                           FROM transaction t, product p, customer c
                           WHERE p.id = t.product_id
                                 AND  c.id = t.customer_id
                                 AND c.id = 1);

然后以某种方式以编程方式将 0 分配给我的结果集中的计数,但我最终会得到两个列表,一个包含产品名称、每个产品的计数以及客户购买的每个产品的价格已使用,另一个列表将包含所有产品名称、计数为 0 以及客户未使用的每种产品的价格。

这可能是一个解决方案,但它似乎远不实用,因为 id 正在处理两个列表并且必须以编程方式分配值而不是处理一个包含我需要的所有数据的列表,这会影响排序等.

我想知道这是否可能,或者是否有其他方法可以解决这个问题。

我希望这已经足够清楚了。我将不胜感激任何对此的见解!

毛里西奥·B.

【问题讨论】:

  • 您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加标签postgresqloracledb2sql-server、...
  • 你需要使用`LEFT OUTER JOIN`
  • 学习使用JOIN。它已经存在了 20 多年!
  • 谢谢大家!我忘了提。我正在使用 MySQL。我的错!

标签: mysql sql


【解决方案1】:

永远不要FROM 子句中使用逗号。 始终使用正确、明确、标准的JOIN 语法。

你的问题是你需要一个left join

select p.id, p.name, Count(t.id), p.price
from product p left join
     transaction t
     on p.id = t.product_id and
        t.customer_id = 1
group by p.price, p.name, p.id
order by p.name asc;

注意:您不需要客户表。 id 在事务表中。

【讨论】:

  • 这正是我想要的!太感谢了。如您所知,我不太擅长 SQL!
【解决方案2】:

这应该适用于大多数 DBMS。它将所有客户产品的事务表分组并获取它们的计数。然后将其与产品连接。由于它是左连接,因此将包括所有产品。对于客户未使用的那些产品,连接列将是NULL。计数也会如此。 coalesce() 函数返回的第一个参数不为空,我们得到 0 作为这些的计数和其他的实际计数。如果您的实际 DBMS 不支持 coalesce(),您可能必须将其替换为相应的 DBMS 特定功能。

SELECT p.id,
       p.name,
       coalesce(t.count, 0) count,
       p.price
       FROM product p
            LEFT JOIN (SELECT t.product_id,
                              count(*) count
                              FROM transaction t
                              WHERE t.customer_id = 1
                              GROUP BY t.product_id) t
                      ON t.product_id = p.id
       ORDER BY p.name ASC;

【讨论】:

  • 很好的解释!感谢您花时间解释这一点!
【解决方案3】:

你必须做两个选择查询并加入它们:

select prodcust.custname, prodcust.prodname, prodcust.prodId, 
    isnull(tranCount,0) as count, prodcust.price 
from
(
    select p.name as prodname, p.id as prodID, c.name as custname, c.id as 
        custid, p.price 
    from product p, customer c
)
as prodcust

left join 

(
    select p.price, p.id, c.id as custid, count(t.id) as tranCount
    from Transaction t
    inner join customer c
       on c.id = t.customer_id
    inner join product p
       on t.product_id = p.id
    group by p.price, p.id, c.id
) as trans 
on prodcust.custid = trans.custid
   and prodcust.prodID = trans.id
order by custname, prodname

【讨论】:

    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 2014-03-01
    相关资源
    最近更新 更多