如何用SQL将Fruit字段唯一值转为列并统计各ID对应计数?
实现SQL行转列统计各ID对应水果出现次数
针对将原表中Fruit字段的唯一值转为单独列,并统计每个ID对应各水果出现次数的需求,可根据水果种类是否固定选择不同实现方式:
1. 静态行转列(已知所有水果种类)
如果提前明确所有水果类型,直接使用CASE WHEN配合聚合函数即可完成统计:
SELECT ID, COUNT(CASE WHEN Fruit = 'Apple' THEN 1 END) AS Apple, COUNT(CASE WHEN Fruit = 'Banana' THEN 1 END) AS Banana, COUNT(CASE WHEN Fruit = 'Orange' THEN 1 END) AS Orange FROM your_table_name -- 替换为你的表名 GROUP BY ID;
原理:通过CASE WHEN匹配每行的水果类型,匹配成功返回1,否则返回NULL;COUNT函数会忽略NULL值,最终得到每个ID对应每种水果的出现次数。
2. 动态行转列(水果种类未知或动态变化)
若水果种类不确定或会新增,需要动态生成SQL语句,不同数据库的实现方式如下:
MySQL
借助GROUP_CONCAT生成动态列的统计语句,再执行:
SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( 'COUNT(CASE WHEN Fruit = ''', Fruit, ''' THEN 1 END) AS ', Fruit ) ) INTO @sql FROM your_table_name; SET @sql = CONCAT('SELECT ID, ', @sql, ' FROM your_table_name GROUP BY ID'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SQL Server
使用PIVOT结合动态SQL实现:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX); SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(Fruit) FROM your_table_name FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,''); SET @query = 'SELECT ID, ' + @cols + ' FROM ( SELECT ID, Fruit FROM your_table_name ) x PIVOT ( COUNT(Fruit) FOR Fruit IN (' + @cols + ') ) p '; EXECUTE(@query);
PostgreSQL
需先启用tablefunc扩展,再使用crosstab函数实现:
-- 启用扩展(仅首次执行) CREATE EXTENSION IF NOT EXISTS tablefunc; SELECT * FROM crosstab( 'SELECT ID, Fruit, COUNT(*) FROM your_table_name GROUP BY ID, Fruit ORDER BY ID, Fruit', 'SELECT DISTINCT Fruit FROM your_table_name ORDER BY Fruit' ) AS ct(ID INT, Apple INT, Banana INT, Orange INT); -- 需按实际水果种类调整列定义
内容的提问来源于stack exchange,提问作者kshinforthewin
相关产品推荐
相关产品推荐

