问题描述
这是我的小提琴https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=7946871d9c25cd8914353c70fde1fe8d
这是我的查询 选择count(user_id)作为itung,从中选择user_Id
(SELECT t1.user_id,t1.createdAt cretecompare1,t2.createdAt cretecompare2,DATEDIFF(t2.createdAt,t1.createdAt) diff
-- table for a transaction
FROM test t1
-- table for prev. transaction
JOIN test t2 ON t1.user_id = t2.user_id
AND t1.createdAt < t2.createdAt
AND 7 NOT IN (t1.status_id,t2.status_id)
JOIN (SELECT t3.user_id
FROM test t3
WHERE t3.status_id != 7
GROUP BY t3.user_id
HAVING SUM(t3.createdAt < '2020-04-01') > 1
AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
WHERE NOT EXISTS (SELECT NULL
FROM test t5
WHERE t1.user_id = t5.user_id
AND t5.status_id != 7
AND t1.createdAt < t5.createdAt
AND t5.createdAt < t2.createdAt)
HAViNG cretecompare2 BETWEEN '2020-02-01' AND '2020-04-01') aa
group by user_Id
output table:
+--------+---------+
| itung | user_Id |
+--------+---------+
| 1 | 13 |
| 2 | 14 |
+--------+---------+
基于该表,我想通过此查询找出max(itung),min(itung)和中位数(itung)
select max(itung),min(itung),format(avg(itung),2),IF(count(*)%2 = 1,CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( GROUP_CONCAT(itung ORDER BY itung SEParaTOR ','),',50/100 * COUNT(*)),-1) AS DECIMAL),ROUND((CAST(SUBSTRING_INDEX(SUBSTRING_INDEX
( GROUP_CONCAT(itung ORDER BY itung SEParaTOR ',50/100
* COUNT(*) + 1),-1) AS DECIMAL) + CAST(SUBSTRING_INDEX(SUBSTRING_INDEX
( GROUP_CONCAT(itung ORDER BY itung SEParaTOR ',50/100
* COUNT(*)),-1) AS DECIMAL)) / 2)) as median from
(select count(user_id) as itung,user_Id from
(SELECT t1.user_id,t2.status_id)
JOIN (SELECT t3.user_id
FROM test t3
WHERE t3.status_id != 7
GROUP BY t3.user_id
HAVING SUM(t3.createdAt < '2020-04-01') > 1
AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
WHERE NOT EXISTS (SELECT NULL
FROM test t5
WHERE t1.user_id = t5.user_id
AND t5.status_id != 7
AND t1.createdAt < t5.createdAt
AND t5.createdAt < t2.createdAt)
HAViNG cretecompare2 BETWEEN '2020-02-01' AND '2020-04-01') aa
group by user_Id) ab
output table:
+------------+------------+-----------------------+--------+
| max(itung) | min(itung) | format(avg(itung),2) | median |
+------------+------------+-----------------------+--------+
| 2 | 1 | 1.50 | 2 |
+------------+------------+-----------------------+--------+
您知道对中位数的查询是错误的,因为中位数应该是1.5,而不是2。我中位数查询的错误之处在哪里?
解决方法
您那里有ROUND()将报告的中位数四舍五入为整数。如果您不想要,请将其删除:
select max(itung),min(itung),format(avg(itung),2),IF(count(*)%2 = 1,CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( GROUP_CONCAT(itung ORDER BY itung SEPARATOR ','),',50/100 * COUNT(*)),-1) AS DECIMAL),(CAST(SUBSTRING_INDEX(SUBSTRING_INDEX ( GROUP_CONCAT(itung ORDER BY itung SEPARATOR ',50/100 * COUNT(*) + 1),-1) AS DECIMAL) + CAST(SUBSTRING_INDEX(SUBSTRING_INDEX ( GROUP_CONCAT(itung ORDER BY itung SEPARATOR ',-1) AS DECIMAL)) / 2) as median
或舍入为整数,然后将其保留为小数位数:3:
select max(itung),ROUND((CAST(SUBSTRING_INDEX(SUBSTRING_INDEX ( GROUP_CONCAT(itung ORDER BY itung SEPARATOR ',-1) AS DECIMAL)) / 2,3)) as median
请注意,仅在行数不多的情况下,才能从GROUP_CONCAT逗号分隔的所有值列表中查找中值,因为GROUP_CONCAT将在@@ group_concat_max_len处被截断,在MySQL或MySQL上默认为1024个字符在10.2之前的MariaDB上。