无法实现T-SQL GROUP BY子句

时间:2013-12-18 06:43:02

标签: sql sql-server tsql group-by aggregate-functions

有人在我陷入沮丧之前帮助我。

我正在创建一个简单的许可投票系统。收到许可证后,委员会必须批准拒绝。该委员会由5名成员组成,投票过程基于多数投票(意味着收到的每份申请都需要批准/拒绝3名或更多委员会成员。例如如果有3名或更多成员投票批准该申请据说是“已批准”,如果3个或更多成员投票拒绝,则说该应用程序被“拒绝”)。

这个想法是,总是需要3个多数票才能确定申请的状态。如果委员会的所有成员都没有投票,或者每个地位(批准或拒绝)的投票数少于3,那么申请被视为“等待”例如,如果2名成员批准并且2拒绝 OR 2批准,1拒绝 OR 1批准,2拒绝 OR 1批准,1拒绝 OR 仅限2批准 OR 仅2拒绝

这是其中一个正在处理的表格的结构

CREATE TABLE [CommitteeApproval](
[CommitteeApprovalID] [int] IDENTITY(1,1) NOT NULL,
[LicenceApplicationID] [int] NOT NULL,
[UserID] [int] NOT NULL,
[ActionDate] [date] NULL,
[CommitteeApprovalStatusID] [int] NOT NULL)

[CommissionApproval] 是主键,而 [LicenceApplicationID] [CommissionApprovalStatusID] [UserID] 是各自表格的外键。

[CommissionApprovalStatus] 表(CommissionApprovalStatus是主键)

   CommitteeApprovalStatusID      CommitteeApprovalStatusName
    1                             Approve
    2                             Reject

[委员会批准] 表包含

LicenceApplicationID UserID ActionDate  CommitteeApprovalStatusID
4173                  37    2013-12-17         2
4173                  36    2013-12-17         1
4173                  6     2013-12-17         1
4173                  7     2013-12-17         1
4174                  37    2013-12-17         1
4174                  36    2013-12-17         2
4174                  7     2013-12-17         2
4174                  6     2013-12-17         2
4174                  38    2013-12-17         2
4176                  38    2013-12-17         2
4177                  7     2013-12-17         2
4179                  36    2013-12-17         1
4179                  38    2013-12-17         2

我想为每个许可证申请返回CommissionApprovalStatus的数量。 例如:对于LicenceApplication 4174 ,4个成员被拒绝,2个成员被批准,因此该应用程序被称为“被拒绝”

我使用以下查询向用户显示被拒绝的应用程序列表

  

SELECT LicenceApplicationID ,CommitteeApprovalStatusID ,COUNT(UserID) AS votes
  FROM CommitteeApproval
  WHERE CommitteeApprovalStatusID=2
  GROUP BY LicenceApplicationID, CommitteeApprovalStatusID
  HAVING COUNT(UserID) >= 3

我还成功检索了具有类似查询的已批准查询列表,但替换为

WHERE CommitteeApprovalStatusID=1

现在,当我尝试检索“待处理”应用程序列表时,会出现问题

  1. 我无法捕获2名成员批准,2名成员被拒绝,1名成员获得批准,1名成员被拒绝,2名成员获得批准,1名成员被拒绝,3名成员被拒绝,1名或2名成员获得批准的申请,2成员被拒绝,3名成员获得批准。

  2. 我一次只能捕获一种类型的应用程序,例如WHERE委员会批准状态ID = 2或1,而我想捕获所有不符合条件的应用程序。

  3. 我写的查询是:

     SELECT LicenceApplicationID, COUNT(UserID) AS votes 
     FROM CommitteeApproval   
     WHERE CommitteeApprovalStatusID=1 
     GROUP BY LicenceApplicationID   
     HAVING COUNT(UserID) < 3
    

    这无济于事我仍然需要用

    写另一个
      

    WHERE CommitteeApprovalStatusID = 2

    它仍然无法捕获问题1中的结果。有没有办法用一个查询显示所有“待定”结果?

4 个答案:

答案 0 :(得分:1)

我的可读性尝试:

WITH votes AS (
  SELECT
    LicenceApplicationID,
    CommitteeApprovalStatusName Vote
  FROM CommitteeApproval A
  INNER JOIN CommitteeApprovalStatus S ON 
    S.CommitteeApprovalStatusID = A.CommitteeApprovalStatusID
)
SELECT
  LicenceApplicationID,
  Approve,
  Reject,
  CASE
    WHEN  Approve >= 3 THEN 'Approved'
    WHEN  Reject  >= 3 THEN 'Rejected'
    ELSE 'Pending'
  END AS VoteStatus
FROM votes
PIVOT(COUNT(Vote) FOR Vote IN (Approve,Reject)) P

答案 1 :(得分:0)

试试这个:

 SELECT LicenceApplicationID, COUNT(UserID) AS votes, 
 CASE  WHEN CommitteeApprovalStatusID = 1 THEN 'Aprove' ELSE 'Rejected' END AS Status
 FROM CommitteeApproval   
 WHERE CommitteeApprovalStatusID in (1, 2) 
 GROUP BY LicenceApplicationID, CommitteeApprovalStatusID    
 HAVING COUNT(UserID) < 3

答案 2 :(得分:0)

尝试此查询

select 
  * 
from 
  (select 
    LicenceApplicationID,
    sum(case when 
          CommitteeApprovalStatusID=1 then 1 
        else 0 end) as pass,
    sum(case when 
          CommitteeApprovalStatusID=2 then 1 
        else 0 end) as fail
    from 
        tbl
    group by 
        LicenceApplicationID
  )tbl 
where 
  pass < 3 and 
  fail < 3

Fiddle

| LICENCEAPPLICATIONID | PASS | FAIL |
|----------------------|------|------|
|                 4176 |    0 |    1 |
|                 4177 |    0 |    1 |
|                 4179 |    1 |    1 |

答案 3 :(得分:0)

试试这个。

(SELECT LicenceApplicationID, COUNT(UserID) As "Votes"
FROM CommitteeApproval
WHERE CommitteeApprovalStatusID = 2) B

SELECT LicenceApplicationID,
CASE 
WHEN A.Votes > 2 THEN "Approved"
WHEN B.Votes >2 THEN  "Rejected"
ELSE "Pending"

END AS "Status"

FROM 

(SELECT LicenceApplicationID, COUNT(UserID) AS "Votes"
FROM CommitteeApproval
WHERE CommitteeApprovalStatusID = 1
GROUP BY LicenceApplicationID ) A 

FULL OUTER JOIN

(SELECT LicenceApplicationID, COUNT(UserID) AS "Votes"
FROM CommitteeApproval
WHERE CommitteeApprovalStatusID = 2
GROUP BY LicenceApplicationID ) B

ON A.LicenceApplicationID = B.LicenceApplicationID