SQL生成多个计数列

时间:2015-04-01 17:08:09

标签: sql sql-server-2008

我开发了一些SQL来生成本地票证数据库表(SQL Server 2008)的统计信息。从我的代码中可以看出,我想从TICKETS中选择,加入group以获取组名,按组代码分组以及年/月。

我想创建总票数(计数),以显示已打开,关闭,在sla之外关闭(过期日期)的票数,以及最终SLA%。

此代码有效,但是我不满意必须编写所有嵌套代码(选择计数);这似乎不是一个多次重新扫描的好策略。

是否有更好的设计可以从表格中的单个选择中生成多个“计数”列...或者这是标准方法吗?

select  g.group_name as [Group],
        year(tm.date_open) as Year,
        month(tm.date_open) as Month,
        COUNT(*) as [Tickets Opened],

        (select COUNT(*)
         from TICKETS tm2
         where tm2.group_code = tm.group_code
         and year(tm2.COMPLETION_DATE) = year(tm.date_open)
         and month(tm2.COMPLETION_DATE) = month(tm.date_open)
        ) as [Tickets Closed],

        (select COUNT(*)
         from TICKETS tm2
         where tm2.group_code = tm.group_code
         and year(tm2.COMPLETION_DATE) = year(tm.date_open)
         and month(tm2.COMPLETION_DATE) = month(tm.date_open)
         and tm2.[COMPLETION_DATE] <= tm2.[DUE_DATE:]
        ) as [Closed Within SLA],   

        (select COUNT(*)
         from TICKETS tm2
         where tm2.group_code = tm.group_code
         and year(tm2.COMPLETION_DATE) = year(tm.date_open)
         and month(tm2.COMPLETION_DATE) = month(tm.date_open)
         and tm2.[COMPLETION_DATE] > tm2.[DUE_DATE:]
        ) as [Closed Outside SLA]   --service level agreement


from TICKETS tm
left join GROUPS g on g.group_code = tm.group_code
where g.group_code in ('techs', 'reps', 'phone')

and year(tm.date_open) = 2015
--and month(tm.date_open) = 3 -- specific month

group by tm.group_code, g.group_name, year(tm.date_open), month(tm.date_open)

order by g.group_name, year(tm.date_open), month(tm.date_open)

我还想要添加一个SLA%列([在SLA内关闭/ [门票关闭])* 100.但是从我目前的设计中看到它,我将不得不添加多余的嵌套选择另一列,例如......

(
    cast((select COUNT(*)
     from TICKETS tm2
     where tm2.group_code = tm.group_code
     and year(tm2.COMPLETION_DATE) = year(tm.date_open)
     and month(tm2.COMPLETION_DATE) = month(tm.date_open)
     and tm2.[COMPLETION_DATE] <= tm2.[DUE_DATE:]
    ) as decimal) /
    (select COUNT(*)
     from TICKETS tm2
     where tm2.group_code = tm.group_code
     and year(tm2.COMPLETION_DATE) = year(tm.date_open)
     and month(tm2.COMPLETION_DATE) = month(tm.date_open)
    )
) * 100 as [SLA%]   

1 个答案:

答案 0 :(得分:3)

是的,你可以比一堆子查询做得更好。在单个聚合查询中,您可以通过计算满足条件时评估为1的各种表达式的SUM()来获得满足不同条件的单独行数,否则为零。或者,您可以COUNT()评估为非NULL的表达式,以准确计算您想要计算的行数。例如,它看起来可能接近您所追求的目标:

SELECT
  g.group_name AS [Group],
  year(tm.date_open) as Year,
  month(tm.date_open) as Month,
  COUNT(*) AS [Tickets Opened],
  COUNT(tm.completion_date) AS [Tickets Closed],
  SUM(CASE WHEN tm.completion_date <= [DUE_DATE:] THEN 1 ELSE 0 END)
    AS [Closed Within SLA],
  SUM(CASE WHEN tm.completion_date > [DUE_DATE:] THEN 1 ELSE 0 END)
    AS [Closed Outside SLA],   --service level agreement
  CAST(SUM(CASE WHEN tm.completion_date <= [DUE_DATE:] THEN 1 ELSE 0 END)
    AS decimal) / COUNT(tm.completion_date)) AS [SLA%],
FROM
  tickets tm
  LEFT JOIN GROUPS g
    ON g.group_code = tm.group_code
WHERE
  g.group_code in ('techs', 'reps', 'phone')
  and year(tm.date_open) = 2015
  -- and month(tm.date_open) = 3 -- specific month
GROUP BY
    tm.group_code,
    g.group_name,
    year(tm.date_open),
    month(tm.date_open)
ORDER BY
    g.group_name,
    year(tm.date_open),
    month(tm.date_open)