SQL查询与计数和连接表

时间:2018-06-04 21:30:50

标签: mysql sql

我有以下三个表:

客户
id(PK)
名称

产品
ID(PK)
命名

交易
ID(PK)
customer_id(FK ref Customer.id)
product_id(FK ref Product.id)
DATE_CREATED

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

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处理两个列表并且必须以编程方式分配值而不是处理一个列表,该列表将包含我需要的所有数据,这将影响排序等

我想知道这是否可行,或者是否有另一种方法可以解决这个问题。

我希望这很清楚。我很感激对此的见解!

Mauricio B。

3 个答案:

答案 0 :(得分:1)

这应该适用于大多数DBMS。它将所有客户产品的交易表分组并计算其数量。然后将其连接到产品上。由于它是左连接,所有产品都将包含在内。对于那些客户未使用已加入列的产品,将为NULL。伯爵也是如此。使用coalesce()函数返回第一个参数not null,我们得到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;

答案 1 :(得分: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;

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

答案 2 :(得分:0)

您必须执行两个选择查询并加入它们:

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