SQL 行变列
已知:数据库
name lesson score
张三 语文 90
李四 数学 94
王五 英语 87
张三 数学 77
李四 语文 80
王五 数学 68
求:如何输出下面的列表(行变列)
语文 数学 英语
张三 90 94
李四 80 94
王五 68 87
答案:
select name,
(select score from t_test where name=o.name and lesson='语文') 语文,
(select score from t_test where name=o.name and lesson='数学') 数学,
(select score from t_test where name=o.name and lesson='英语') 英语
from t_test o group by name
这只是一个静态的sql语句,也就是说,语文,数学和英语这三门课程我们是假定知道的。如果不知道呢?那就只能动态的拼sql语句了。先从数据库中取这些课程然后再拼sql。
usertype表
| ChargeName |
| 小车 |
| 大车 |
| 中巴 |
| 免费 |
统计后的收费表
SELECT Operator, ChargeType, SUM(Price) AS price
FROM InOutList
GROUP BY Operator, ChargeType
ORDER BY Operator, ChargeType
| Operator | ChargeType | price |
| System | 大车 | 160 |
| System | 免费 | 0 |
| System | 小车 | 40 |
| System | 中巴 | 45 |
| 冯丽 | 大车 | 0 |
| 冯丽 | 免费 | 0 |
| 冯丽 | 小车 | 510 |
| 冯丽 | 中巴 | 15 |
| 焦艳玲 | 大车 | 60 |
| 卢建玲 | 大车 | 100 |
| 马春艳 | 大车 | 220 |
| 徐金涛 | 免费 | 0 |
| 徐金涛 | 小车 | 240 |
| 徐金涛 | 中巴 | 30 |
| 杨天明 | 大车 | 0 |
| 岳红胜 | 免费 | 0 |
| 岳红胜 | 小车 | 80 |
| 张新乐 | 免费 | 0 |
| 张新乐 | 小车 | 190 |
要求的效果如下:
| operator | 小车 | 大车 | 中巴 | 免费 |
| System | 40 | 160 | 45 | 0 |
| 冯丽 | 510 | 0 | 15 | 0 |
| 焦艳玲 | 0 | 60 | 0 | 0 |
| 卢建玲 | 0 | 100 | 0 | 0 |
| 马春艳 | 0 | 220 | 0 | 0 |
| 徐金涛 | 240 | 0 | 30 | 0 |
| 杨天明 | 0 | 0 | 0 | 0 |
| 岳红胜 | 80 | 0 | 0 | 0 |
| 张新乐 | 190 | 0 | 0 | 0 |
实现:
declare @sql varchar(8000)
set @sql='select bb.operator'
select @sql=@sql+','+usertype.ChargeName+'=isnull(sum(case chargetype when '''+usertype.ChargeName+''' then bb.price end),0) 'from usertype
set @sql=@sql+' from (SELECT Operator, ChargeType, SUM(Price) AS price
FROM InOutList
GROUP BY Operator, ChargeType) bb group by operator order by operator'
--print @sql
exec(@sql)
浙公网安备 33010602011771号