1. 程式人生 > >關於MySQL中查詢語句行轉列分組的問題

關於MySQL中查詢語句行轉列分組的問題

今天遇到一個SQL的小問題,首先需要按天查詢資料,並且需要統計每一個不同位置的資料條數,處理的時候卡住了,特此記錄一下:
#首先,第一次寫的SQL如下,先按天分組,後按指定條件分組:
SELECT
    id,
    DATE_FORMAT(created_date, '%Y-%m-%d') selectDay,
    count_location countLocation,
    COUNT(DISTINCT user_id) counts
FROM counter
WHERE id = 32
GROUP BY
    DATE_FORMAT(created_date, '%Y-%m-%d'
),count_location ORDER BY DATE_FORMAT(created_date, '%Y-%m-%d') DESC

查詢結果如下圖所示:
第一次查詢結果

此時需要將每天的資料合併到同一天的資料中去,實際需要的結果如下圖所示:
需要實現的效果

所以接下來實際需要處理得問題就是將多行一列轉為一行多列:
可以利用子查詢查詢出初始結果,再使用case…when…end進行合併,SQL如下:

SELECT
    SELECT1.selectDay,
    IFNULL(CASE SELECT1.countLocation WHEN 'downPay' THEN   SELECT1.counts END
,0) AS 'downPay', IFNULL(CASE SELECT1.countLocation WHEN 'villaDetail' THEN SELECT1.counts END,0) AS 'villaDetail', IFNULL(CASE SELECT1.countLocation WHEN 'materials' THEN SELECT1.counts END,0) AS 'materials', IFNULL(CASE SELECT1.countLocation WHEN 'vr' THEN SELECT1.counts END,0) AS
'vr', IFNULL(CASE SELECT1.countLocation WHEN 'goDownPay' THEN SELECT1.counts END,0) AS 'goDownPay' FROM ( SELECT id, DATE_FORMAT(created_date, '%Y-%m-%d') selectDay, count_location countLocation, COUNT(DISTINCT user_id) counts FROM counter WHERE id = 32 GROUP BY DATE_FORMAT(created_date, '%Y-%m-%d'),count_location ORDER BY DATE_FORMAT(created_date, '%Y-%m-%d') DESC ) SELECT1 GROUP BY SELECT1.selectDay,SELECT1.countLocation ORDER BY SELECT1.selectDay DESC

但是,這時候會發現,結果還是不對,丟失了一些資料,再分組的時候,只取到了第一條資料,如圖所示:
這裡寫圖片描述
加上另一個條件進行分組,結果如下:
這裡寫圖片描述
可以看出每一行資料都有一個統計好的資料,就相當於,這些資料還是分行統計了,沒有合併到同一條,這時只需要加上一個MAX()函式,取每一行的最大值即可,得到最終資料,SQL如下:

SELECT
    SELECT1.selectDay,
    MAX(IFNULL(CASE SELECT1.countLocation WHEN 'downPay' THEN   SELECT1.counts END,0)) AS 'downPay',
    MAX(IFNULL(CASE SELECT1.countLocation WHEN 'villaDetail' THEN   SELECT1.counts END,0)) AS 'villaDetail',
    MAX(IFNULL(CASE SELECT1.countLocation WHEN 'materials' THEN SELECT1.counts END,0)) AS 'materials',
    MAX(IFNULL(CASE SELECT1.countLocation WHEN 'vr' THEN SELECT1.counts END,0)) AS 'vr',
    MAX(IFNULL(CASE SELECT1.countLocation WHEN 'goDownPay' THEN SELECT1.counts END,0)) AS 'goDownPay'
FROM
    (
        SELECT
            id,
            DATE_FORMAT(created_date, '%Y-%m-%d') selectDay,
            count_location countLocation,
            COUNT(DISTINCT user_id) counts
        FROM
            counter
        WHERE
            id = 32
        GROUP BY
            DATE_FORMAT(created_date, '%Y-%m-%d'),count_location
        ORDER BY
            DATE_FORMAT(created_date, '%Y-%m-%d') DESC
    ) SELECT1
GROUP BY SELECT1.selectDay
ORDER BY
    SELECT1.selectDay DESC