SQL根据主题计算出现次数

时间:2013-12-30 17:58:49

标签: sql oracle pivot jpql

我发现很难说出我想要实现的目标。我有一张看起来像这样的表:

user char
---------
a | x
a | y
a | z
b | x
b | x
b | y
c | y
c | y
c | z

如何编写一个可以返回以下结果的查询?

user x y z
-------
a |1|1|1|
b |2|1|0|
c |0|2|1|

数字表示原始表格中出现的字符数

编辑: 字符值未知,因此解决方案不能限于这些值。很抱歉没有提及它。我正在使用Oracle DB,但计划使用JPQL构建查询。

3 个答案:

答案 0 :(得分:6)

select user,
    sum(case when char='x' then 1 else 0 end) as x,
    sum(case when char='y' then 1 else 0 end) as y,
    sum(case when char='z' then 1 else 0 end) as z
from thetable
group by user

或者,如果您不介意垂直堆叠,此解决方案将为您提供一个解决方案,即使使用未知的字符集也可以使用:

select user, char, count(*) as count
from thetable
group by user, char

这会给你:

user   char   count
a      x      1
a      y      1
a      z      1
b      x      2

如果要将一组未知的值水平排出(如在演示输出中),则需要进入动态查询...... SQL标准不是为了生成具有未知数字的输出而设计的列...希望这有用!

答案 1 :(得分:0)

另一种选择,使用T-SQL PIVOT (SQL SERVER 2005+)

select *
from userchar as t
pivot
(
    count([char]) for [char] in ([x],[y],[z]) 
) as p

结果:

user        x           y           z
----------- ----------- ----------- -----------
a           1           1           1
b           2           1           0
c           0           2           1

(3 row(s) affected)

编辑ORACLE

您可以使用ORACLE构建类似的PIVOT表。

棘手的部分是您需要在IN ([x],[y],[z],...)语句中使用正确的列名。在代码中构造SQL查询,获取(SELECT DISTINCT [char] from table)并将其附加到基本查询应该不会太难。

Pivoting rows into columns dynamically in Oracle

答案 2 :(得分:0)

如果您不知道PIVOT的确切值,您可能需要执行某些程序性操作或使用动态sql(在匿名块内),或使用XML(在11g中)。

如果您想要XML方法,它将类似于:

with x as (
  select 'a' as usr, 'x' as val from dual
  union all
  select 'a' as usr, 'y' as val from dual
  union all
  select 'b' as usr, 'x' as val from dual
  union all
  select 'b' as usr, 'x' as val from dual
  union all
  select 'c' as usr, 'z' as val from dual
)
select * from x
pivot XML (count(val) as val_cnt for val in (ANY))
;

输出:

USR VAL_XML
a   <PivotSet><item><column name = "VAL">x</column><column name = "VAL_CNT">1</column></item><item><column name = "VAL">y</column><column name = "VAL_CNT">1</column></item></PivotSet>
b   <PivotSet><item><column name = "VAL">x</column><column name = "VAL_CNT">2</column></item></PivotSet>
c   <PivotSet><item><column name = "VAL">z</column><column name = "VAL_CNT">1</column></item></PivotSet>

希望有所帮助