2

考虑这个简单的查询:

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

但我想避免子选择,特别是因为所有必要的值都已经存在于第一个查询的结果中。这将需要聚合值的聚合,但我不知道该怎么做。有任何想法吗?

4

2 回答 2

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
于 2013-08-14T22:44:34.413 回答
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。通常,将表称为“表”是不可移植的。

于 2013-08-14T22:49:09.747 回答