考虑这个简单的查询:
SELECT
year(t.date) AS y,
month(t.date) AS m,
t.person_id AS id,
count(*) AS freq
FROM
table t
WHERE
t.date>='2013-01-01' AND t.date<='2013-06-30'
GROUP BY y, m, id
这产生了这样的结果:
y m id freq
------------------
2013 1 100 2
2013 1 101 7
2013 1 102 1
2013 2 100 5
2013 2 101 4
2013 2 102 11
...
我想添加一个列,其中包含每个月频率总和的频率百分比,例如:
y m id freq perc
-----------------------
2013 1 100 2 20
2013 1 101 7 70
2013 1 102 1 10
2013 2 100 5 25
2013 2 101 4 20
2013 2 102 11 55
...
到目前为止,我的解决方案是将其添加到select子句中:
count(*) * 100 / (SELECT count(*) FROM table WHERE year(date)=y AND month(date)=m) AS perc
但我想避免使用子选择,特别是因为所有必要的值都已存在于第一个查询的结果中。这需要汇总聚合值,但我不知道如何做到这一点。有什么想法吗?
答案 0 :(得分:0)
SELECT
year(t.date) AS y,
month(t.date) AS m,
t.person_id AS id,
COUNT(*) AS freq,
CASE WHEN p.freq = 0 then 0
ELSE (CAST(COUNT(*) as FLOAT) / p.freq) * 100
END AS rate
FROM table t
JOIN (
SELECT
year(t.date) AS y,
month(t.date) AS m,
count(*) AS freq
FROM table
GROUP BY y, m
) p ON p.y = year (t.date) AND p.m = month (t.date)
WHERE t.date BETWEEN '2013-01-01' AND '2013-06-30'
GROUP BY y, m, id
答案 1 :(得分:0)
如果没有你提出的那种子查询,MySQL就无法做到这一点。但是,要使数字添加到100%,您应该小心确保查询的分母包含与分子兼容的WHERE子句。
在您提出的解决方案中,您不会得到总计100%。
使用您建议的查询而不添加其他列
SELECT
year(t.date) AS y,
month(t.date) AS m,
t.person_id AS id,
count(*) AS freq
FROM
table t
WHERE
t.date>='2013-01-01' AND t.date<='2013-06-30'
GROUP BY y, m, id
作为起点,您想要的最终查询是:
SELECT
year(t.date) AS y,
month(t.date) AS m,
t.person_id AS id,
count(*) AS freq,
(count(*) * 100) /
(
select count(*)
from table t
where t.date>='2013-01-01'
AND t.date<='2013-06-30'
)
FROM
table t
WHERE
t.date>='2013-01-01' AND t.date<='2013-06-30'
GROUP BY y, m, id
我建议使用已知问题的查询表(称为表)将产生错误。在我做的小测试中,我将其重命名为t1。通常,调用表'table'是不可移植的。