CASE语句中使用IN运算符的值应计数一次

时间:2018-08-23 15:54:52

标签: sql sql-server

我希望这有助于解释更多的标题。基本上我有一个查询:

SELECT 
  e.USER
, e.CODE
, CASE WHEN 
  e.CODE IN ('a.01', 'b.04', 'c.20', x.01)
  THEN 1
  ELSE NULL
  END AS case
FROM TABLE e

那会让我:

USER   CODE     case
01     a.01     1
01     a.02     NULL
01     a.04     NULL
01     b.04     1
01     c.20     1
02     a.11     NULL
02     b.04     1
03     b.05     NULL
04     c.20     1

但是,我需要的是有点复杂。我需要对代码进行分组,以便为​​每个用户USER每组提供一个值:

例如:

, CASE WHEN 
  e.CODE IN ('a.01', 'b.04') --Group A
  OR
  e.CODE IN ('c.20', x.01)   --Group B
  THEN 1
  ELSE NULL
  END AS case

上面的代码是错误的,因为我需要的是,如果存在用户的GROUP A或GROUP B中的至少一个代码,则仅给出1 ELSE NULL的一个值。

可能会产生的东西

USER   CODE     case
01     a.01     1    --Group A
01     a.02     NULL
01     a.04     NULL
01     b.04     NULL --GROUP A, now NULL because we just need to count once per group 
01     c.20     1    --GROUP B
02     a.11     NULL
02     b.04     1   
03     b.05     NULL
04     c.20     1

如果这有帮助,我最终想对每个用户计算出以下内容:

USER     count
01       2       --Not 3
02       1
03       1
04       1

5 个答案:

答案 0 :(得分:1)

您只能使用MAILGUN_API_KEY=3fe2*****ae1a MAILGUN_DOMAIN=sandbox*****d5cb.mailgun.org MAILGUN_KEY=3fe2****ae1a MAILGUN_PUBLIC_KEY=pubkey-b******a MAILGUN_SMTP_LOGIN='postmaster@sandbox*******.mailgun.org' MAILGUN_SMTP_PASSWORD=b018******7840 MAILGUN_SMTP_PORT=587 MAILGUN_SMTP_SERVER=smtp.mailgun.org MAILGUN_VALIDATIONS_PUBLIC_KEY='[200]' 来为每个用户设置一次值:

ROW_NUMBER()

编辑:

对于评论中的修订问题:

SELECT e.USER, e.CODE,
       (CASE WHEN ROW_NUMBER() OVER (PARTITION BY flag, e.USER ORDER BY e.code) = 1
             THEN flag
        END) as flag
FROM (SELECT e.*,
             (CASE WHEN e.CODE IN ('a.01', 'b.04', 'c.20', x.01) THEN 1 END) as flag
      FROM TABLE e
     ) e;

答案 1 :(得分:1)

我敢肯定有一种更聪明的方法,但是如果我理解正确的话,这可能会解决问题:

SELECT sub.user,
       sub.code,
       CASE WHEN ROW_NUMBER() OVER
                 ( PARTITION BY GroupCode
                       ORDER BY inGroup DESC
                 ) = 1 
             AND MAX(inGroup) OVER
                 ( PARTITION BY GroupCode
                 ) = 1 THEN 1 
            ELSE 0
        END FieldYourAskingFor       
  FROM (SELECT e.*,
               CASE WHEN e.CODE IN ('a.01', 'b.04', 'c.20', x.01) THEN 1 
                END AS inGroup,
               CASE WHEN e.CODE IN ('a.01', 'b.04') THEN 'GroupA'
                    WHEN e.CODE IN ('c.20', x.01) THEN 'GroupB'
                END AS GroupCode
          FROM TABLE e
       ) sub

答案 2 :(得分:1)

我将row_number()case表达式一起使用:

select USER, CODE, 
       (case when row_number() over (partition by USER, grp order by CODE) = 1 and
                  grp is not null 
             then 1
        end) as case
from ( select *, (case when CODE IN ('a.01', 'b.04') then 'GA' 
                       when CODE IN ('c.20', 'x.01') then 'GB' 
                  end) as grp
       from table
    ) t;

答案 3 :(得分:1)

这就是我要做的方式。

-- create test table and data
declare @tbl table(usr char(2), code char(4))
insert into @tbl values ('01', 'a.01'), ('01', 'b.04')
insert into @tbl values ('01', 'c.20'), ('02', 'b.04'), ('04', 'c.20')

-- actual query
select
   usr,
   sign(sum(iif(code in ('a.01', 'b.04'), 1, 0))) +          -- 1 if group a, else 0  
   sign(sum(iif(code in ('c.20', 'x.01'), 1, 0))) as count   -- 1 if group b, else 0
from @tbl
group by usr

输出为:

usr count
--- -----
01      2
02      1
04      1

答案 4 :(得分:0)

我感谢您的反馈。我正在发布有效的答案,但不确定最佳答案:

SELECT
   t.USER
  ,t.CODE
  ,COUNT DISTINCT(t.case)

FROM (

SELECT 
  e.USER
, e.CODE
, CASE 
  WHEN e.CODE IN ('a.01', 'b.04') --Group A
  THEN 'grpA'
  WHEN e.CODE IN ('c.20', x.01)   --Group B
  THEN 'grpB'
  ELSE NULL
  END AS case

FROM TABLE e
) t

GROUP BY t.USER

我意识到这将使我得到按用户分组的结果,但最终效果与我一样,我只想按用户计数案件。不知道是否有人可以使用它来获得更好的格式。