2

我有 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多个。是否可以有动态的CASE WHEN?获取当月所有服务以及每项服务的退货数量。它也应该在服务的 AS 名称之后写我。另一种选择是我手动编写这 100 个服务,所以我只是想知道?谢谢

4

3 回答 3

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

那么问题就变成了:当你不知道你会得到多少列时,你真的需要一个透视结果集吗?

于 2012-05-17T11:47:09.913 回答
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 IMMEDIATEStatement

于 2012-05-17T11:53:06.470 回答
1
select 
    service,
    monthname (timestamp_iso(STATUSDATE)), 
    count (*)              
from 
    INCIDENT
where 
    service in ('ADSL','IPTV','VOIP')
group by 
    monthname(timestamp_iso(STATUSDATE)), 
    service

我认为这会让你接近你想要的。

于 2012-05-17T11:46:06.993 回答