MySQL 将多行的选定列合并为一个
MySQL Combining selected columns of multiple rows into one
我想计算每个年龄段每个宗教的男性和女性用户的数量,以获得结果 table,如下面的第三个 table。
我有两个 table 如下:
tbl_user
+----+----------+------------+--------+-----------+
| id | name | dob | gender | religion |
+----+----------+------------+--------+-----------+
| 1 | raj | 1999-12-21 | m | 1 |
| 7 | raju | 1998-10-10 | m | 2 |
| 8 | rajan | 2000-11-23 | m | 3 |
| 11 | neetu | 1992-12-06 | f | 1 |
| 12 | sita | 1993-06-16 | f | 2 |
| 13 | rita | 1992-06-08 | f | 3 |
| 14 | jenny | 1993-05-10 | f | 2 |
| 15 | manju | 1993-12-16 | f | 1 |
| 16 | aanju | 1993-03-05 | f | 3 |
| 17 | raja | 1995-04-06 | m | 1 |
| 18 | rajendra | 1995-07-03 | m | 2 |
| 19 | rajesh | 1991-05-02 | m | 3 |
+----+----------+------------+--------+-----------+
tbl_religion
+----+-----------+
| id | name |
+----+-----------+
| 1 | Christian |
| 2 | Hindu |
| 3 | Islam |
+----+-----------+
宗教 table 可以有任意数量的记录(宗教)。
现在我想计算每个年龄段每个宗教的男性和女性用户数量,以获得如下所示的结果 table。用户可以是任何年龄或出生于任何年份:
+-----+----------------+------------------+------------+--------------+------------+--------------+
| Age | Christian Male | Christian Female | Hindu Male | Hindu Female | Islam Male | Islam Female |
+-----+----------------+------------------+------------+--------------+------------+--------------+
| 14 | 0 | 0 | 0 | 0 | 1 | 0 |
| 15 | 1 | 0 | 0 | 0 | 0 | 0 |
| 16 | 0 | 0 | 1 | 0 | 0 | 0 |
| 20 | 1 | 0 | 1 | 0 | 0 | 0 |
| 21 | 0 | 1 | 0 | 0 | 0 | 0 |
| 22 | 0 | 1 | 0 | 2 | 0 | 1 |
| 23 | 0 | 0 | 0 | 0 | 1 | 1 |
| 24 | 0 | 0 | 0 | 0 | 0 | 0 |
+-----+----------------+------------------+------------+--------------+------------+--------------+
感谢您的帮助。
对于前两个 tables
select count(a.id) as 'Population',
timestampdiff(year,a.dob,current_date)as 'Age',
b.name as 'Religion'
from tbl_user a
inner join tbl_religion b on a.ethnicity=b.name
group by
timestampdiff(year,a.dob,current_date),
b.name
第三个table
select sum(Christian_Male)+sum(Christian_Female)as 'Christian',
sum(Hindu_Male)+sum(Hindu_Female)as 'Hindu',
sum(Islam_Male)+sum(Islam_Female)as 'Islam',
Age
from religion_table
group by
Age
在 , we can use the method described in this q/a 的基础上使查询动态化,以便它处理未知数量的宗教。
最终查询将如下所示:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'sum(gender = ''', gender,
''' and r.name = ''',
r.name, ''') AS "',
if(gender='m','Male','Female'),
' ', r.name, '" '
)
) INTO @sql
FROM
tbl_user u
JOIN
tbl_religion r ON u.religion = r.id;
SET @sql = CONCAT(
'select timestampdiff(year, dob, now()) age, ', @sql, '
from tbl_user u
join tbl_religion r on u.religion = r.id
group by timestampdiff(year, dob, now());');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
您可以手动 select 列:
SELECT
TIMESTAMPDIFF(YEAR, u.dob, CURRENT_DATE) AS 'Age',
SUM(CASE
WHEN r.name = 'Christian' AND u.gender = 'm' THEN 1
ELSE 0
END) AS 'Christian Male',
SUM(CASE
WHEN r.name = 'Christian' AND u.gender = 'f' THEN 1
ELSE 0
END) AS 'Christian Female'
FROM tbl_user u
LEFT JOIN tbl_religion r ON r.id = u.religion
但是您需要针对每个新宗教更改您的查询。我想您应该生成一个中间查询,然后使用数据透视函数将描述转置到多个列中:
SELECT
TIMESTAMPDIFF(YEAR, u.dob, CURRENT_DATE) AS 'Age',
CONCAT(r.name, ' ', CASE
WHEN u.gender = 'm' THEN 'Male'
WHEN u.gender = 'f' THEN 'Female'
ELSE 'Unknown'
END) AS 'Description'
FROM tbl_user u
LEFT JOIN tbl_religion r ON r.id = u.religion
Wich 为您提供以下输出:
+-----+------------------+
| Age | Description |
+-----+------------------+
| 14 | Christian Male |
| 15 | Christian Female |
| 16 | Hindu Male |
| 20 | Hindu Female |
| 21 | Islam Male |
+-----+------------------+
然后使用 Pivot、Excel 或其他工具将其转换为所需的输出。我不知道这是否可以直接在 MySQL 中完成,但是关于这个有多个 SO 问题。
我想计算每个年龄段每个宗教的男性和女性用户的数量,以获得结果 table,如下面的第三个 table。
我有两个 table 如下:
tbl_user
+----+----------+------------+--------+-----------+
| id | name | dob | gender | religion |
+----+----------+------------+--------+-----------+
| 1 | raj | 1999-12-21 | m | 1 |
| 7 | raju | 1998-10-10 | m | 2 |
| 8 | rajan | 2000-11-23 | m | 3 |
| 11 | neetu | 1992-12-06 | f | 1 |
| 12 | sita | 1993-06-16 | f | 2 |
| 13 | rita | 1992-06-08 | f | 3 |
| 14 | jenny | 1993-05-10 | f | 2 |
| 15 | manju | 1993-12-16 | f | 1 |
| 16 | aanju | 1993-03-05 | f | 3 |
| 17 | raja | 1995-04-06 | m | 1 |
| 18 | rajendra | 1995-07-03 | m | 2 |
| 19 | rajesh | 1991-05-02 | m | 3 |
+----+----------+------------+--------+-----------+
tbl_religion
+----+-----------+
| id | name |
+----+-----------+
| 1 | Christian |
| 2 | Hindu |
| 3 | Islam |
+----+-----------+
宗教 table 可以有任意数量的记录(宗教)。
现在我想计算每个年龄段每个宗教的男性和女性用户数量,以获得如下所示的结果 table。用户可以是任何年龄或出生于任何年份:
+-----+----------------+------------------+------------+--------------+------------+--------------+
| Age | Christian Male | Christian Female | Hindu Male | Hindu Female | Islam Male | Islam Female |
+-----+----------------+------------------+------------+--------------+------------+--------------+
| 14 | 0 | 0 | 0 | 0 | 1 | 0 |
| 15 | 1 | 0 | 0 | 0 | 0 | 0 |
| 16 | 0 | 0 | 1 | 0 | 0 | 0 |
| 20 | 1 | 0 | 1 | 0 | 0 | 0 |
| 21 | 0 | 1 | 0 | 0 | 0 | 0 |
| 22 | 0 | 1 | 0 | 2 | 0 | 1 |
| 23 | 0 | 0 | 0 | 0 | 1 | 1 |
| 24 | 0 | 0 | 0 | 0 | 0 | 0 |
+-----+----------------+------------------+------------+--------------+------------+--------------+
感谢您的帮助。
对于前两个 tables
select count(a.id) as 'Population',
timestampdiff(year,a.dob,current_date)as 'Age',
b.name as 'Religion'
from tbl_user a
inner join tbl_religion b on a.ethnicity=b.name
group by
timestampdiff(year,a.dob,current_date),
b.name
第三个table
select sum(Christian_Male)+sum(Christian_Female)as 'Christian',
sum(Hindu_Male)+sum(Hindu_Female)as 'Hindu',
sum(Islam_Male)+sum(Islam_Female)as 'Islam',
Age
from religion_table
group by
Age
在
最终查询将如下所示:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'sum(gender = ''', gender,
''' and r.name = ''',
r.name, ''') AS "',
if(gender='m','Male','Female'),
' ', r.name, '" '
)
) INTO @sql
FROM
tbl_user u
JOIN
tbl_religion r ON u.religion = r.id;
SET @sql = CONCAT(
'select timestampdiff(year, dob, now()) age, ', @sql, '
from tbl_user u
join tbl_religion r on u.religion = r.id
group by timestampdiff(year, dob, now());');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
您可以手动 select 列:
SELECT
TIMESTAMPDIFF(YEAR, u.dob, CURRENT_DATE) AS 'Age',
SUM(CASE
WHEN r.name = 'Christian' AND u.gender = 'm' THEN 1
ELSE 0
END) AS 'Christian Male',
SUM(CASE
WHEN r.name = 'Christian' AND u.gender = 'f' THEN 1
ELSE 0
END) AS 'Christian Female'
FROM tbl_user u
LEFT JOIN tbl_religion r ON r.id = u.religion
但是您需要针对每个新宗教更改您的查询。我想您应该生成一个中间查询,然后使用数据透视函数将描述转置到多个列中:
SELECT
TIMESTAMPDIFF(YEAR, u.dob, CURRENT_DATE) AS 'Age',
CONCAT(r.name, ' ', CASE
WHEN u.gender = 'm' THEN 'Male'
WHEN u.gender = 'f' THEN 'Female'
ELSE 'Unknown'
END) AS 'Description'
FROM tbl_user u
LEFT JOIN tbl_religion r ON r.id = u.religion
Wich 为您提供以下输出:
+-----+------------------+
| Age | Description |
+-----+------------------+
| 14 | Christian Male |
| 15 | Christian Female |
| 16 | Hindu Male |
| 20 | Hindu Female |
| 21 | Islam Male |
+-----+------------------+
然后使用 Pivot、Excel 或其他工具将其转换为所需的输出。我不知道这是否可以直接在 MySQL 中完成,但是关于这个有多个 SO 问题。