【问题标题】:WHERE containing certain values, with CASE containing additional valueWHERE 包含某些值,CASE 包含附加值
【发布时间】:2020-07-22 15:59:54
【问题描述】:

我正在尝试查询名为 DeviceGroups 的表,该表包含 2 列 MachineIDGroupID。这是一个例子

    MachineID GroupID
   ------------------
    1          A1
    1          A3
    2          A2
    3          A2
    3          A3
    4          A4
    4          A5
    5          A3

我需要显示包含 GroupID A1 或 A2 的所有 MachineID,如果该 MachineID 还包含 A3,则使用单独的列给出是/否。这是预期的结果:

MachineID GroupID ContainsA3?
------------------------------
1         A1      Yes
2         A2      No
3         A2      Yes

注意 MachineID 4 和 5 未列出,因为它们不包含 A1 或 A2,即使 MachineID 5 包含 A3。我无法创建 WHERE 子句来仅过滤 A1 和 A2,因为所有结果都将显示 ContainsA3?为假,如果我包含 A3,则 MachineID 5 将出现,GroupID 为 NULL,这也是不允许的。有任何想法吗?这是我卡住的地方:

SELECT MachineID,
CASE WHEN GroupID = 3 then "Yes" Else "No" END AS [ContainsA3?]
FROM DeviceGroups

结果如下:

MachineID ContainsA3?
-----------------
1          No
1          Yes
2          No
3          No
3          Yes
4          No
4          No
5          Yes

如果我添加 WHERE 子句:

SELECT MachineID,
CASE WHEN GroupID = 3 then "Yes" Else "No" END AS [ContainsA3?]
FROM DeviceGroups
WHERE GroupID = 3

MachineID ContainsA3?
-----------------
1          Yes
3          Yes
5          Yes

【问题讨论】:

  • 如果一台机器属于 A1 A2组怎么办?

标签: sql sql-server tsql sql-server-2008 group-by


【解决方案1】:

考虑:

select
    MachineID,
    max(case when GroupID in ('A1', 'A2') then GroupID end) GroupID,
    max(case when GroupID = 'A3' then 'Yes' else 'No' end) ContainsA3
from mytable
where GroupID in ('A1', 'A2', 'A3')
group by MachineID
having max(case when GroupID in ('A1', 'A2') then 1 end) = 1

想法是使用where 子句过滤组A1、A2 和A3,按机器聚合,并使用having 子句确保看到A1 或A2。其余的是select 子句中的条件聚合。

【讨论】:

    【解决方案2】:

    您可以使用子查询

    SELECT groups.MachineID
    , ISNULL(
        (SELECT 'Yes' FROM DeviceGroups 
             WHERE MachineID = groups.MachineID AND GroupID = 3)
        , 'No'
    ) AS [ContainsA3?]
    FROM DeviceGroups groups
    WHERE groups.GroupID IN (1, 2)
    GROUP BY groups.MachineID 
    

    【讨论】:

      【解决方案3】:

      据我所知,子查询可以完成这项工作:

      SELECT MachineID, 
      CASE WHEN GroupID in ('A1','A2') 
      and 'A3'  in (select GroupID from DeviceGroups as dv 
                    where DeviceGroups.MachineID = dv.MachineID) 
                    then 'Yes' Else 'No' END AS [ContainsA3?] 
      FROM DeviceGroups
      

      【讨论】:

        【解决方案4】:
        create table #tbl ( 
        mID int,
        gID varchar(2) )    
        
        
        insert into #tbl
        values
        (1, 'A1'),
        (1, 'A3'),
        (2, 'A2'),
        (3, 'A2'),
        (3, 'A3'),
        (4, 'A4'),
        (4, 'A5'),
        (5, 'A3')
        
        
        select a.*, case when b.gID is not null then 'Yes' else 'No' end as ContainsA3
        from #tbl a
        left join #tbl b
        on b.mID = a.mID
        and b.gID = 'A3'
        where a.gID in ('A1','A2')
        
        
        
        mID  gID    ContainsA3
        1    A1     Yes
        2    A2     No
        3    A2     Yes
        

        【讨论】:

          猜你喜欢
          • 2021-02-01
          • 2013-11-22
          • 2018-03-25
          • 1970-01-01
          • 1970-01-01
          • 2015-08-22
          • 1970-01-01
          • 1970-01-01
          • 2014-08-16
          相关资源
          最近更新 更多