计算范围百分比
Calculate percentages on ranges
我有以下 table 数据:
+----------+------------+-----------+
| country | age | gender |
+----------+------------+-----------+
| China | 15 | male |
+----------+------------+-----------+
| China | 25 | female |
+----------+------------+-----------+
| China | 50 | male |
+----------+------------+-----------+
| China | 62 | male |
+----------+------------+-----------+
| Burma | 25 | female |
+----------+------------+-----------+
| Burma | 50 | male |
+----------+------------+-----------+
| France | 27 | male |
+----------+------------+-----------+
| France | 55 | female |
+----------+------------+--------- -+
我想查询 select,结果如下:
+----------+-----------+---------+-----------+-----------------+----------------+
| region | age_range | gender | count | gender_percent | total_percent |
+----------+-----------+---------+-----------+-----------------+----------------+
| Asia | 0-49 | male | 1 | 33 | 12.5 |
+----------+---------- +---------+-----------+-----------------+----------------+
| Asia | 0-49 | female | 2 | 67 | 25 |
+----------+-----------+---------+-----------+--------------- -+----------------+
| Asia | 50+ | male | 3 | 100 | 37.5 |
+----------+-----------+---------+-----------+-----------------+----------------+
| Europe | 0-49 | male | 1 | 100 | 12.5 |
+----------+-----------+---------+-----------+-----------------+----------------+
| Europe | 50+ | female | 1 | 100 | 12.5 |
+----------+-----------+------- -+-----------+-----------------+----------------+
即。我想计算数据范围的不同百分比。每个国家(地区)和年龄段的性别各占一个百分比,占总数各占一个百分比。
我该怎么做?
我更喜欢交叉 RDBMS 解决方案,它尽可能减少硬编码。速度和简单性也是主要方面。我正在 MySQL 上开发,但该解决方案稍后将移植到 Oracle 和 MS SQL。
非常感谢。
我把地区作为国家的一列。在 select 中,我使用 CASE 来获取范围标签。如果不想添加 region
字段
,您可以对 region
执行相同的操作
CREATE TABLE country
(`region` varchar(6), `country` varchar(6), `age` int, `gender` varchar(6))
;
INSERT INTO country
(`region`, `country`, `age`, `gender`)
VALUES
('Asia', 'China', 15, 'male'),
('Asia', 'China', 25, 'female'),
('Asia', 'China', 50, 'male'),
('Asia', 'China', 62, 'male'),
('Asia', 'Burma', 25, 'female'),
('Asia', 'Burma', 50, 'male'),
('Europe', 'France', 27, 'male'),
('Europe', 'France', 55, 'female')
;
SELECT region.*,
(count_range_gender / region_range_total.gender_total) * 100 as gender_percent,
(count_range_gender / world.world_total) * 100 as total_percent
FROM
(
SELECT `region`,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END age_range,
gender,
count(country) as count_range_gender
FROM country
GROUP BY `region`,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END,
gender
) region
JOIN
(
SELECT `region`,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END age_range,
count(country) as gender_total
FROM country
GROUP BY `region`,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END
) region_range_total
ON region.region = region_range_total.region
AND region.age_range = region_range_total.age_range
CROSS JOIN
(
SELECT count(country) as world_total
FROM country
) world
输出
| region | age_range | gender | count_range_gender | gender_percent | total_percent |
|--------|-----------|--------|--------------------|----------------|---------------|
| Asia | 0-49 | female | 2 | 66.6667 | 25 |
| Asia | 0-49 | male | 1 | 33.3333 | 12.5 |
| Asia | 50+ | male | 3 | 100 | 37.5 |
| Europe | 0-49 | male | 1 | 100 | 12.5 |
| Europe | 50+ | female | 1 | 100 | 12.5 |
编辑
在MySql中你也可以使用IF(age < 50, '0-49', '50+')
这里是完整的答案。无论如何,如果没有@Juan Carlos Oropeza 的回答,我将无法做到。再次感谢胡安 :-)
SELECT region.*,
(`count` / region_range_total.gender_total) * 100 as gender_percent,
(`count` / (select count(*) from country)) * 100 as total_percent
FROM
(
SELECT
CASE country
WHEN 'China' then 'Asia'
WHEN 'Burma' then 'Asia'
WHEN 'France' then 'Europe'
END region,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END age_range,
gender,
count(country) as `count`
FROM country
GROUP BY
region,
age_range,
gender
) region
JOIN
(
SELECT
CASE country
WHEN 'China' then 'Asia'
WHEN 'Burma' then 'Asia'
WHEN 'France' then 'Europe'
END region,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END age_range,
count(country) as gender_total
FROM country
GROUP BY
region,
age_range
) region_range_total
ON region.region = region_range_total.region
AND region.age_range = region_range_total.age_range
我有以下 table 数据:
+----------+------------+-----------+
| country | age | gender |
+----------+------------+-----------+
| China | 15 | male |
+----------+------------+-----------+
| China | 25 | female |
+----------+------------+-----------+
| China | 50 | male |
+----------+------------+-----------+
| China | 62 | male |
+----------+------------+-----------+
| Burma | 25 | female |
+----------+------------+-----------+
| Burma | 50 | male |
+----------+------------+-----------+
| France | 27 | male |
+----------+------------+-----------+
| France | 55 | female |
+----------+------------+--------- -+
我想查询 select,结果如下:
+----------+-----------+---------+-----------+-----------------+----------------+
| region | age_range | gender | count | gender_percent | total_percent |
+----------+-----------+---------+-----------+-----------------+----------------+
| Asia | 0-49 | male | 1 | 33 | 12.5 |
+----------+---------- +---------+-----------+-----------------+----------------+
| Asia | 0-49 | female | 2 | 67 | 25 |
+----------+-----------+---------+-----------+--------------- -+----------------+
| Asia | 50+ | male | 3 | 100 | 37.5 |
+----------+-----------+---------+-----------+-----------------+----------------+
| Europe | 0-49 | male | 1 | 100 | 12.5 |
+----------+-----------+---------+-----------+-----------------+----------------+
| Europe | 50+ | female | 1 | 100 | 12.5 |
+----------+-----------+------- -+-----------+-----------------+----------------+
即。我想计算数据范围的不同百分比。每个国家(地区)和年龄段的性别各占一个百分比,占总数各占一个百分比。
我该怎么做?
我更喜欢交叉 RDBMS 解决方案,它尽可能减少硬编码。速度和简单性也是主要方面。我正在 MySQL 上开发,但该解决方案稍后将移植到 Oracle 和 MS SQL。
非常感谢。
我把地区作为国家的一列。在 select 中,我使用 CASE 来获取范围标签。如果不想添加 region
字段
region
执行相同的操作
CREATE TABLE country
(`region` varchar(6), `country` varchar(6), `age` int, `gender` varchar(6))
;
INSERT INTO country
(`region`, `country`, `age`, `gender`)
VALUES
('Asia', 'China', 15, 'male'),
('Asia', 'China', 25, 'female'),
('Asia', 'China', 50, 'male'),
('Asia', 'China', 62, 'male'),
('Asia', 'Burma', 25, 'female'),
('Asia', 'Burma', 50, 'male'),
('Europe', 'France', 27, 'male'),
('Europe', 'France', 55, 'female')
;
SELECT region.*,
(count_range_gender / region_range_total.gender_total) * 100 as gender_percent,
(count_range_gender / world.world_total) * 100 as total_percent
FROM
(
SELECT `region`,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END age_range,
gender,
count(country) as count_range_gender
FROM country
GROUP BY `region`,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END,
gender
) region
JOIN
(
SELECT `region`,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END age_range,
count(country) as gender_total
FROM country
GROUP BY `region`,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END
) region_range_total
ON region.region = region_range_total.region
AND region.age_range = region_range_total.age_range
CROSS JOIN
(
SELECT count(country) as world_total
FROM country
) world
输出
| region | age_range | gender | count_range_gender | gender_percent | total_percent |
|--------|-----------|--------|--------------------|----------------|---------------|
| Asia | 0-49 | female | 2 | 66.6667 | 25 |
| Asia | 0-49 | male | 1 | 33.3333 | 12.5 |
| Asia | 50+ | male | 3 | 100 | 37.5 |
| Europe | 0-49 | male | 1 | 100 | 12.5 |
| Europe | 50+ | female | 1 | 100 | 12.5 |
编辑
在MySql中你也可以使用IF(age < 50, '0-49', '50+')
这里是完整的答案。无论如何,如果没有@Juan Carlos Oropeza 的回答,我将无法做到。再次感谢胡安 :-)
SELECT region.*,
(`count` / region_range_total.gender_total) * 100 as gender_percent,
(`count` / (select count(*) from country)) * 100 as total_percent
FROM
(
SELECT
CASE country
WHEN 'China' then 'Asia'
WHEN 'Burma' then 'Asia'
WHEN 'France' then 'Europe'
END region,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END age_range,
gender,
count(country) as `count`
FROM country
GROUP BY
region,
age_range,
gender
) region
JOIN
(
SELECT
CASE country
WHEN 'China' then 'Asia'
WHEN 'Burma' then 'Asia'
WHEN 'France' then 'Europe'
END region,
CASE WHEN age < 50 then '0-49'
ELSE '50+'
END age_range,
count(country) as gender_total
FROM country
GROUP BY
region,
age_range
) region_range_total
ON region.region = region_range_total.region
AND region.age_range = region_range_total.age_range