今天遇到一个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