SQL顺序IF条件

时间:2014-07-09 14:11:44

标签: sql sql-server

我有一张名为Tasks的表格。我想总结任务状态类型(打开,关闭)和按项目分组的优先级的数量。

这样的事情:

===============================================================================================
| Project   |   Closed  |   Major   |   Moderate    |   Minor   | Total 
===============================================================================================
|Project 1  |   4       |   3       |   0           |   0       | 7
|Project 2  |   1       |   0       |   2           |   5       | 8
|Project 3  |   10      |   8       |   3           |   4       | 25

"优先级"取决于在VarChar字段中查找关键字的能力。 (我知道,非常糟糕,但没有问题)

我无法弄清楚的部分是如何编写查询,以便我确定优先级为" Major",中断或继续下一个任务。一旦我确定优先级为" Major"应忽略其他优先级(中等和次要)。同样适用于"中等"。如果我发现"中等"我不应该担心未成年人。 这是我遇到问题的部分。 如何根据其他选择的结果创建if语句?

这就是我到目前为止所给出的所有重要信息......但优先事项不是"链接"或取决于父母的匹配条件。

SELECT  Project, 
        count(status) as "Status Count"
        ,sum(case when status = 'Closed' then 1 else 0 end) as Closed
        ,sum(case when status = 'Open' then 1 else 0 end) as "Open"
        ,sum(case when CHARINDEX ( 'Major', DefectSummary COLLATE Latin1_General_CI_AS) > 0 then 1 else 0 end) as Major
        ,sum(case when CHARINDEX ( 'Moderate', DefectSummary COLLATE Latin1_General_CI_AS) > 0 then 1 else 0 end) as Moderate
        ,sum(case when CHARINDEX ( 'Minor', DefectSummary COLLATE Latin1_General_CI_AS) > 0 then 1 else 0 end) as Minor

FROM Tasks
GROUP BY Project

免责声明 :我知道这是一个糟糕的数据模型。我从之前的开发人员那里继承了它。我正在检修整个系统,但我需要能够像现在一样生成报告,直到我完成新系统。

3 个答案:

答案 0 :(得分:3)

我会使用子查询来确定优先级,然后在外部查询中使用它:

SELECT  Project
        ,count(status) as "Status Count"
        ,sum(case when status = 'Closed' then 1 else 0 end) as Closed
        ,sum(case when status = 'Open' then 1 else 0 end) as "Open"
        --
        ,sum(case when priority = 'Major' then 1 else 0 end) as Major
        ,sum(case when priority = 'Moderate' then 1 else 0 end) as Moderate
        ,sum(case when priority = 'Minor' then 1 else 0 end) as Minor
        ,sum(case when priority = 'Unknown' then 1 else 0 end) as Unknown
from
( select t.*
  ,      case
         when CHARINDEX ( 'Major', DefectSummary COLLATE Latin1_General_CI_AS) > 0
         then 'Major'
         when CHARINDEX ( 'Moderate', DefectSummary COLLATE Latin1_General_CI_AS) > 0
         then 'Moderate'
         when CHARINDEX ( 'Minor', DefectSummary COLLATE Latin1_General_CI_AS) > 0
         then 'Minor'
         else 'Unknown'
         end
         priority
  from   tasks t
) tasks
GROUP
BY    Project

答案 1 :(得分:1)

一种方法是使用子字符串搜索结果准备数据源,将该源公开为公用表表达式(CTE),并将GROUP BY基于该源:< / p>

WITH Task_CTE (Project, Status, Closed, Open, Major, Moderate, Minor)
AS (
    SELECT
        Project, 
        status
    ,   case when status = 'Closed' then 1 else 0 end as Closed
    ,   case when status = 'Open' then 1 else 0 end as "Open"
    ,   case when CHARINDEX ( 'Major', DefectSummary COLLATE Latin1_General_CI_AS) > 0 then 1 else 0 end as Major
    ,   case when CHARINDEX ( 'Moderate', DefectSummary COLLATE Latin1_General_CI_AS) > 0 then 1 else 0 end as Moderate
    ,   case when CHARINDEX ( 'Minor', DefectSummary COLLATE Latin1_General_CI_AS) > 0 then 1 else 0 end as Minor
    FROM Tasks
)
SELECT
    Project
,   count(status)
,   sum(Closed) as Closed
,   sum("Open") as "Open"
,   sum(Major) as Major
,   sum(CASE WHEN Major=1 THEN 0 ELSE Moderate END) as Moderate
,   sum(CASE WHEN Major=1 OR Moderate=1 THEN 0 ELSE Minor END) as Minor
FROM Task_CTE
GROUP BY Project

使用这种方法可以让您的分组SELECT看到&#34; raw&#34; CTE SELECT。在上面的查询中,当'Moderate'出现时,'Minor''Major'的标记会被忽略。

答案 2 :(得分:0)

如果您想修改优先级列表,可以将其与查询逻辑分开:

DECLARE @DefectPriorities TABLE ([Priority] int, [DefectType] varchar(max))
INSERT @DefectPriorities VALUES
  (1,'Major'    ), 
  (2,'Moderate' ),
  (3,'Minor'    )

;WITH t1 AS (
  SELECT
    [Project]
   ,[DefectType]
   ,COUNT(CASE [Status] WHEN 'Closed' THEN 1 END) [Closed]
   ,COUNT(*) [Total]
  FROM tasks t2
  OUTER APPLY (
    SELECT TOP 1 [DefectType]
    FROM @Priorities
    WHERE CHARINDEX([DefectType],[DefectSummary] COLLATE Latin1_General_CI_AS) > 0
    ORDER BY [Priority]
  ) t3
  GROUP BY [Project],[DefectType]
)
SELECT *
FROM t1
PIVOT(COUNT([DefectType]) FOR [DefectType] IN ('Major','Moderate','Minor') ) t4