【问题标题】:Trouble implementing T-SQL GROUP BY clause执行 T-SQL GROUP BY 子句时遇到问题
【发布时间】:2013-12-18 06:43:01
【问题描述】:

在我陷入抑郁之前有人帮助我。

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

这个想法是始终需要 3 个多数票来确定应用程序的状态。如果委员会的所有成员都没有投票或每个状态(批准或拒绝)的投票数少于 3,则应用程序被称为 “待处理” 例如,如果 2 个成员批准并且2 个拒绝 OR 2 个批准和 1 个拒绝 OR 1 个批准和 2 个拒绝 OR 1 个批准和 1 个拒绝 OR 仅限2 个批准只有 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)

[CommitteeApproval] 是主键,而 [LicenceApplicationID][CommitteeApprovalStatusID][UserID]是它们各自表的外键。

[CommitteeApprovalStatus] 表(CommitteeApprovalStatus 为主键)

   CommitteeApprovalStatusID      CommitteeApprovalStatusName
    1                             Approve
    2                             Reject

[CommitteeApproval] 表格包含

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

我想返回每个许可证申请的 CommitteeApprovalStatus 编号。 例如:对于LicenceApplication4174,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 CommitteeApprovalStatusID=2 或 1,而我想捕获所有不符合条件的申请。

我写的查询是:

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

这并没有多大帮助,因为我仍然需要用

写另一个

WHERE CommitteeApprovalStatusID=2

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

【问题讨论】:

  • 您是否尝试过使用case statements 将其放在 sqlfiddle.com 中的大约 20 行

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


【解决方案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

【讨论】:

    【解决方案2】:

    试试这个:

     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
    

    【讨论】:

    • 它没有给我所有的结果 :( :( 虽然我从@Anon 得到了更准确的结果 检查其他 cmets 或 stackoverflow.com/a/20669261/3041930
    【解决方案3】:

    试试这个查询

    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 |
    

    【讨论】:

    • 它工作但没有显示所有结果。 @Anon 刚刚给了我一个更准确的解决方案。检查其他 cmets 或stackoverflow.com/a/20669261/3041930(我真的很感激你帮助顺便说一句)
    【解决方案4】:

    试试这个。

    (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
    

    【讨论】:

    • A 和 B 代表什么?我正在使用 MS-SQL Server 2008,它们被识别为不正确的语法
    • 它们是表别名。用“AS”明确地给它们起别名。
    猜你喜欢
    • 1970-01-01
    • 2020-09-20
    • 2018-09-07
    • 2013-01-27
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    相关资源
    最近更新 更多