2017-10-17 28 views
0

我有以下表格产品和测试。加入两个表并计数,如果第二个表中不存在记录,则避免为零

select id,pname from products;              
+----+---------+                 
| id | pname |                 
+----+---------+                 
| 1 | prd1 |                 
| 2 | prd2 |                 
| 3 | prd3 |                 
| 4 | prd4 |                 
+----+---------+              

select pname,testrunid,testresult,time from tests;      
+--------+-----------+------------+-------------+         
| pname | testrunid | testresult | time  |         
+--------+-----------+------------+-------------+         
| prd1 |  800 | PASS  | 2017-10-02 |         
| prd1 |  801 | FAIL  | 2017-10-16 |         
| prd1 |  802 | PASS  | 2017-10-02 |         
| prd1 |  803 | NULL  | 2017-10-16 |         
| prd1 |  804 | PASS  | 2017-10-16 |         
| prd1 |  805 | PASS  | 2017-10-16 |         
| prd1 |  806 | PASS  | 2017-10-16 |         
+--------+-----------+------------+-------------+  

我喜欢统计产品的测试结果,如果没有可用的结果,产品只显示为零。像下表:

+--------+------------+-----------+----------------+---------------+    
| pname | total_pass | total_fail| pass_lastweek | fail_lastweek |    
+--------+------------+-----------+----------------+---------------+    
| prd1 |  5  |  1  |  3   |  1  |    
| prd2 |  0  |  0  |  0   |  0  |    
| prd3 |  0  |  0  |  0   |  0  |    
| prd4 |  0  |  0  |  0   |  0  |    
+--------+------------+-----------+----------------++--------------+ 

我试图像下面,这是刚刚工作的一个产品和不同的查询是不完整的:

SELECT pname, count(*) as pass_lastweek FROM tests where testresult = 'PASS' AND time 
>= '2017-10-11' and pname in (select pname from products) group by pname;  
+-------------+---------------+             
| pname  | pass_lastweek |             
+-------------+---------------+             
| prd1  |   3 |             
+-------------+---------------+ 

它看起来如此基本的,但我仍不能写, 任何想法?

+0

PNAME不会是任何明智设计的测试表中的列。除此之外,这是非常基础的,并将在任何基础的入门书籍或教程中得到彻底解决。 – Strawberry

+0

'SELECT a.pname,b.testrunid FROM products as a LEFT JOIN test as B on a.pname = b.pname where b.testresulty ='PASS'and b.time> ='2017-10-11'and group通过a.pname' – parkway

回答

3

使用条件聚合。 COUNT函数将自动计数为NULL的值为零,因此,不需要照顾它。

select p.pname, 
     count(case when testresult = 'PASS' then 1 end) as total_pass, 
     count(case when testresult = 'FAIL' then 1 end) as total_fail, 
     count(case when testresult = 'PASS' and time >= curdate() - INTERVAL 6 DAY then 1 end) as pass_lastweek , 
     count(case when testresult = 'FAIL' and time >= curdate() - INTERVAL 6 DAY then 1 end) as fail_lastweek , 
from products p 
left join tests t on t.pname = p.pname 
group p.id, p.pname 
0

一般情况下,你需要在第一个表和第二个表之前分组。每个产品(即使没有测试结果加入它,INNER JOIN将排除没有关联测试的产品)+每个测试结果(超出第一个)的附加行,连接将为您提供每行产品的连续行。然后你可以将它们分组。

SELECT products.*, tests.* FROM products 
LEFT JOIN tests ON products.pname = tests.pname 
GROUP BY products.id 

另外,我想强烈建议在测试表使用product_id列,而不是使用pname(如果products.pname的变化,你的整个DB休息,除非你也以实物更新PNAME场每个测试结果)。那么一般的查询应该是这样的:

SELECT products.*, tests.* FROM products 
LEFT JOIN tests ON products.id = tests.product_id 
GROUP BY products.id 
0

我用了2个查询,先用条件计数,第二个是改变所有值到0:

select pname, 
    case when total_pass is null then 0 else total_pass end as total_pass, 
    case when total_fail is null then 0 else total_fail end as total_fail, 
     case when pass_lastweek is null then 0 else pass_lastweek end as pass_lastweek, 
     case when fail_lastweek is null then 0 else fail_lastweek end asfail_lastweek from (
    select products.pname, 
      count(case when testresult = 'PASS' then 1 end) as total_pass, 
      count(case when testresult = 'FAIL' then 1 end) as total_fail, 
      count(case when testresult = 'PASS' and time >= current_date -7 DAY then 1 end) as pass_lastweek , 
      count(case when testresult = 'FAIL' and time >= current_date -7 DAY then 1 end) as fail_lastweek , 
    from products 
    left join tests on tests.pname = products.pname 
    group 1) t1 
相关问题