2011-12-20 249 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