2011-12-20 202 views
3

我在数据库中使用了两个表。 第一个包含与成功和失败付款相关的数据,而第二个表包含有关服务状态的数据。Mysql内部联接查询

查询的结果应该将两个表结合起来,结果列出按日期分组的成功和失败付款以及按天分组的服务状态。

第一个表的样子:

id | charged | date 
----------------------------- 
8 | OK  | 2011-12-03 
7 | OK  | 2011-12-03 
9 | NO  | 2011-12-03 
11 | OK  | 2011-12-04 
14 | NO  | 2011-12-04 

第二个表是这样的:

id | status | date 
-------------------------- 
8 | 1 | 2011-12-03 
9 | 1 | 2011-12-03 
11 | 0 | 2011-12-04 
12 | 0 | 2011-12-04 
14 | 1 | 2011-12-04 

正确的查询结果应该是:

date | not_charged | charged | status_1 | status_0 
----------------------------------------------------------- 
2011-12-04 |  1  | 1  | 1  | 2 
2011-12-03 |  1  | 2  | 2  | 0 

,我试过查询看起来像这样:

SELECT i.date, SUM(
CASE WHEN i.charged = 'NO' 
THEN 1 ELSE 0 END) AS not_charged, SUM(
CASE WHEN i.charged = 'OK' 
THEN 1 ELSE 0 END) AS charged, SUM(
CASE WHEN s.status = '1' 
THEN 1 ELSE 0 END) AS status_1, SUM(
CASE WHEN s.status = '0' THEN 1 ELSE 0 END) AS status_0 
FROM charge i INNER JOIN status s ON s.date = i.date 
GROUP BY i.date 

,但我得到错误的结果看起来像这样

date | not_charged | charged | status_1 | status_0 
--------------------------------------------------------- 
2011-12-04 |  3  | 3 | 2  | 4 
2011-12-03 |  2  | 4 | 6  | 0 

我在做什么错了,我怎样才能得到正确的结果?

感谢您的所有建议。

回答

1

尝试这一个 -

SELECT date, 
    SUM(IF(charged = 'NO', 1, 0)) not_charged, 
    SUM(IF(charged = 'OK', 1, 0)) charged, 
    SUM(IF(status = 1, 1, 0)) status_1, 
    SUM(IF(status = 0, 1, 0)) status_0 
FROM (
    SELECT date, charged, NULL status FROM charge 
    UNION ALL 
    SELECT date, NULL charged, status FROM status 
    ) t 
    GROUP BY date DESC; 

+------------+-------------+---------+----------+----------+ 
| date  | not_charged | charged | status_1 | status_0 | 
+------------+-------------+---------+----------+----------+ 
| 2011-12-04 |   1 |  1 |  1 |  2 | 
| 2011-12-03 |   1 |  2 |  2 |  0 | 
+------------+-------------+---------+----------+----------+ 
+0

+1:如果记录不需要与他们的ID相关,最简洁的选项。 – MatBailie 2011-12-20 17:38:14

1

这个假设是有关服务状态及付款状态一起...

SELECT 
    COALESCE(charge.date, status.date)      AS date, 
    SUM(CASE WHEN charge.charged = 'NO' THEN 1 ELSE 0 END) AS not_charged, 
    SUM(CASE WHEN charge.charged = 'OK' THEN 1 ELSE 0 END) AS charged, 
    SUM(CASE WHEN status.status = '0' THEN 1 ELSE 0 END) AS status_0, 
    SUM(CASE WHEN status.status = '1' THEN 1 ELSE 0 END) AS status_1 
FROM 
    charge 
FULL OUTER JOIN 
    status 
    ON charge.id = status.id 
GROUP BY 
    COALESCE(charge.date, status.date) 

注意,我注意到知道你想怎么处理7(无状态记录)和12个ID列(无收费记录)。目前这只是计数有什么。


另外,如果你不想通过相关ID的记录,你仍然可以按日期涉及,但你需要改变你的逻辑。

目前你得到这个,因为你只通过日期涉及...

id | charged | date   id | status | date 
----------------------------- -------------------------- 
8 | OK  | 2011-12-03  8 | 1 | 2011-12-03 
8 | OK  | 2011-12-03  9 | 1 | 2011-12-03 

7 | OK  | 2011-12-03  8 | 1 | 2011-12-03 
7 | OK  | 2011-12-03  9 | 1 | 2011-12-03 

9 | NO  | 2011-12-03  8 | 1 | 2011-12-03 
9 | NO  | 2011-12-03  9 | 1 | 2011-12-03 

11 | OK  | 2011-12-04  11 | 0 | 2011-12-04 
11 | OK  | 2011-12-04  12 | 0 | 2011-12-04 
11 | OK  | 2011-12-04  14 | 1 | 2011-12-04 

14 | NO  | 2011-12-04  11 | 0 | 2011-12-04 
14 | NO  | 2011-12-04  12 | 0 | 2011-12-04 
14 | NO  | 2011-12-04  14 | 1 | 2011-12-04 


相反,你需要将数据整合到1元每桌日期,然后加入...

SELECT 
    COALESCE(charge.date, status.date) AS date, 
    charge.not_charged, 
    charge.charged, 
    status.status_0, 
    status.status_1 
FROM 
    (
    SELECT 
    date, 
    SUM(CASE WHEN charged = 'NO' THEN 1 ELSE 0 END) AS not_charged, 
    SUM(CASE WHEN charged = 'OK' THEN 1 ELSE 0 END) AS  charged 
    FROM 
    charge 
    GROUP BY 
    date 
) 
    AS charge 
FULL OUTER JOIN 

    (
    SELECT 
    date, 
    SUM(CASE WHEN charged = '0' THEN 1 ELSE 0 END) AS status_0, 
    SUM(CASE WHEN charged = '1' THEN 0 ELSE 1 END) AS status_1 
    FROM 
    status 
    GROUP BY 
    date 
) 
    AS status 
    ON charge.date = status.date 

还有其他的方法,但希望这可以解释一下你。

0

我建议使用UNION ALL:

select date, 
     coalesce(sum(not_charged),0) not_charged, 
     coalesce(sum(charged),0) charged, 
     coalesce(sum(status_1),0) status_1, 
     coalesce(sum(status_0),0) status_0 
from (select date, 
      case charged when 'NO' then 1 end not_charged, 
      case charged when 'OK' then 1 end charged, 
      0 status_1, 
      0 status_0 
     from charge 
     union all 
     select date, 
      0 not_charged, 
      0 charged, 
      case status when '1' then 1 end status_1, 
      case status when '0' then 1 end status_0 
     from status) sq 
group by date 
+0

会预聚合之前UNION,以及后,保存任何资源成本? – MatBailie 2011-12-20 17:22:43

+0

据我所知 - 如果有的话,我会期待一个(非常)轻微的性能影响,因为相同的数据将被汇总两次,尽管我怀疑实际差异太小而无法分辨。 – 2011-12-20 17:25:31