今天在做项目时,需要将数据库中的一个表的数据倒置(行变成列),使用了case when 关键字,说到这里,我也总结一下如何将数据库中的行变为列。
数据倒置:
(case when 太强大了)
1、这有一张礼品寄送表gift_send:
sendid是主键,giftid是礼品的id,num是当前送出去的个数,giftname是礼品的名称。
2、我现在需要统计每个礼品在某一天送出去的数量,如下图:
3、上图的sql语句为:
select time,
sum(case giftid when 6 then num else 0 end) as "10元话费/个" ,
sum(case giftid when 7 then num else 0 end) as "20元话费/个" ,
sum(case giftid when 17 then num else 0 end) as "30元话费/个"
from gift_send
group by time
4、如果想统计在某段时间内每个礼品在某一天送出去的数量,可以加上where或having子句。此sql语句的关键是以时间分组。
5、如果想统计某个礼品在某段时间总共送出去的个数,及对应统计中的“合计”,则将time和group by time去掉,即不以时间分组,sum全部数量。如下图:
6、如果想要统计某天的全部话费的费用,即不管是10元的,20元的,30元的等,全部话费的总和。如下图:
(文章中的排序,标号完全是为了看着方便,没有实际作用)
是不是感觉case when 很强大,通过这样我们就可以做各种统计和合计了,好了,现在转入正题(说这么多了,才开始正题,嘻嘻)
HQL中case when 问题
这么强大的功能,用sql语句是没有问题的,在sqlplus中也可以顺利执行,以上面的为证。可是,我一用HQL语句(将sql中的表名换成hibernate对应的实体),就各种错误。
由于我用的是oracle,所以我写select * from gift_send as g where g.time='2014-02-11'这条语句时,报错:找不到右括号或没有关键字form等,原因是oracle不识别表别名as,起别名直接写在表的后面,去掉成功。
然后就是各种错误,例如:
1、org.hibernate.QueryException: unexpected char: '"'
2、org.hibernate.hql.ast.QuerySyntaxException: unexpected token:
3、at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException
等等,网上查了一上午,没有解决,有人说case when 是sql的关键字,hql不支持,等等,
解决办法:我是将其作为普通的sql语句执行的,用hibernate的createSQLQuery方法。