有可能有动态COUNT(CASE WHEN)声明吗?

时间:2012-05-17 11:41:22

标签: sql case-when

我有SQL查询,它运行正常。

select monthname (timestamp_iso(STATUSDATE)), 

    count (case when service='ADSL' then 1 end) as  ADSL,
    count (case when service='IPTV' then 1 end) as  IPTV,
    count (case when service='VOIP' then 1 end) as  VOIP
from INCIDENT
group by monthname(timestamp_iso(STATUSDATE))

我每个月都会获得该月的服务数量。 但这些服务我有100多个。 有可能有动态的情况吗?获取所有服务以及每个服务在该月返回的数量。它也应该在服务的AS名称后写我。 另一个选择是我手动编写这100个服务,所以我只是想知道? 感谢

3 个答案:

答案 0 :(得分:3)

SQL中不能包含动态数量的列。

您可以编写将SQL写入执行(动态SQL)的代码(使用SQL或其他语言编写),但这可能会变得混乱。 WSo,生成的SQL查询适用于固定数量的列,但是每次运行时都有更改SQL查询的代码。

符合您需求且不需要动态重新编码的标准关系数据库模型是规范化您的结果......

SELECT
  monthname (timestamp_iso(STATUSDATE)),
  service,
  COUNT(*) AS count_service
FROM
  incident
GROUP BY
  monthname(timestamp_iso(STATUSDATE)),
  service

然后问题变成:当你不知道你会得到多少列时,你真的需要一个可旋转的结果集吗?

答案 1 :(得分:2)

如果您想这样做,可以使用编程语言select DISTINCT service构建查询

例如在C#

string SQL = "select monthname (timestamp_iso(STATUSDATE))" 

List<string> Columns = new List<string>();
foreach(string service in Services)
{
     Columns.Add( "  count (case when service='"+service+"' then 1 end) as  "+service);
}

SQL +="," + String.Join(",",Columns.ToArray());
SQL += " from INCIDENT group by monthname(timestamp_iso(STATUSDATE))";

db.Query(SQL);

在Javascript中:

  var SQL = "select monthname (timestamp_iso(STATUSDATE))"; 

var Columns = new Array();
foreach(string service in Services)
{
     Columns.push( "  count (case when service='"+service+"' then 1 end) as  "+service);
}

SQL +="," + Columns.Join(',');
SQL += " from INCIDENT group by monthname(timestamp_iso(STATUSDATE))";

db.Query(SQL);

其他方式如果您使用oracle,您可以尝试编写PL / SQL来选择列,并动态构建查询,然后使用EXECUTE IMMEDIATE语句

答案 2 :(得分:1)

select 
    service,
    monthname (timestamp_iso(STATUSDATE)), 
    count (*)              
from 
    INCIDENT
where 
    service in ('ADSL','IPTV','VOIP')
group by 
    monthname(timestamp_iso(STATUSDATE)), 
    service

我认为这可以让你接近你想要的东西。