问题描述
+-------+---------+----------+-------+
| type | ip | line | count |
+-------+---------+----------+-------+
| x | 1 | EN | 10 |
| x | 1 | FR | 10 |
| x | 2 | EN | 5 |
| x | 5 | EN | 5 |
| y | 3 | CH | 10 |
| y | 3 | PT | 10 |
| y | 4 | PT | 10 |
| y | 6 | EN | 10 |
+-------+---------+----------+-------+
我正在尝试根据ip的内部类型来计算行的百分比。实际上计数不用于计算百分比,我只查看特定行的数目并将其除以行的总数。所以,我希望看到这样的结果,我在桌子旁边举个例子。
+-------+---------+----------+
| line | type | percent |
+-------+---------+----------+
| EN | x | %100 |--> There are 3 EN and 3 ip inside the X,So 3/3=%100
| FR | x | %33 |
| CH | y | %33 |
| PT | y | %66 |
| EN | y | %33 |
+-------+---------+----------+
所以,我尝试但我无法在sql中达到该结果。
解决方法
请考虑以下内容...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY,line CHAR(2) NOT NULL,type CHAR(1) NOT NULL,ip INT NOT NULL
);
INSERT INTO my_table (line,type,ip) VALUES
('EN','x',1),('FR',('EN',2),5),('CH','y',3),('PT',4),6);
SELECT line,COUNT(*) line_count FROM my_table GROUP BY line,type;
+------+------+------------+
| line | type | line_count |
+------+------+------------+
| CH | y | 1 |
| EN | x | 3 |
| EN | y | 1 |
| FR | x | 1 |
| PT | y | 2 |
+------+------+------------+
SELECT type,COUNT(DISTINCT ip) ip_count FROM my_table GROUP BY type;
+------+----------+
| type | ip_count |
+------+----------+
| x | 3 |
| y | 3 |
+------+----------+
然后结合以上内容...
SELECT a.line,a.type,a.line_count/b.ip_count * 100 pct
FROM
( SELECT line,type) a
JOIN
( SELECT type,COUNT(DISTINCT ip) ip_count FROM my_table GROUP BY type) b
ON b.type = a.type;
+------+------+----------+
| line | type | pct |
+------+------+----------+
| CH | y | 33.3333 |
| EN | x | 100.0000 |
| EN | y | 33.3333 |
| FR | x | 33.3333 |
| PT | y | 66.6667 |
+------+------+----------+
,
在单个查询期间,MySQL聚合功能只能使用一个分组。因此,您无法根据原始数据计算百分比,因为您需要同时包含X行的行总数和每行并同时键入的行数。
您可以做的是利用临时表,您将在其中进行第一次分组并计算每行的行数:
create temporary table test_total
select line,count(*) as total
from test
group by line
然后,您可以在第二个查询中联接该表:
select t.line,t.type,count(*),tt.total,round(count(*)/tt.total * 100,2)
from test t
join test_total as tt on tt.line = t.line
group by t.line,t.type