2016-06-20 187 views
1

是否有更方便更简单的方法来编写下列SQL代码?SQL嵌套子查询与计数

SELECT 
       products.name, 
       (SELECT COUNT(*) FROM `sales` WHERE sales.product_id = products.id AND sales.payment_method = 'debt') AS debt, 
       (SELECT COUNT(*) FROM `sales` WHERE sales.product_id = products.id AND sales.payment_method = 'cash') AS cash, 
       (SELECT COUNT(*) FROM `sales` WHERE sales.product_id = products.id AND sales.payment_method = 'free') AS free 

      FROM `sales`, `products` 
      WHERE `sales`.`product_id` = `products`.`id` 
      GROUP BY `products`.`id` 

回答

1

你可以基于该Payment_method条件SUM()聚集:

Select P.name, 
     Sum(Case When S.Payment_method = 'debt' Then 1 Else 0 End) As Debt, 
     Sum(Case When S.Payment_method = 'cash' Then 1 Else 0 End) As Cash, 
     Sum(Case When S.Payment_method = 'free' Then 1 Else 0 End) As Free 
From Sales  S 
Join Products P On S.Product_id = P.Id 
Group By P.Name 

我还添加了别名,使其更具可读性,并改变了GROUP BYP.Name而非P.IdP.Id没有出现在SELECT声明中,而MySQL允许这样做,结果留给编译器,这可能会给你一些意想不到的东西。

+0

我可以添加另一个JOIN语句? '在S.time <= mytime上加入S' –

+0

应该将其作为'WHERE'子句添加,而不是'JOIN'语句。 – Siyual

+0

您可能还想添加条件:'where S.Payment_method in('debt','cash','free'')。这不会改变结果,但可以提高性能。 –

1
SELECT p.name, 
     SUM(IF(s.payment_method = 'debt',1,0)) debt, 
     SUM(IF(s.payment_method = 'cash',1,0)) cash, 
     SUM(IF(s.payment_method = 'free',1,0)) free 
FROM products p 
JOIN sales s 
ON s.product_id = p.id 
GROUP BY p.id 

更新据@jpw评论,我同意,可以简化为:

​​
+2

您可以将条件进一步降低为SUM(s.payment_method ='debt')',因为MySQL会将布尔表达式评估为1或0.) – jpw