WHERE, содержащий определенные значения, с CASE, содержащий дополнительное значение - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь запросить таблицу с именем DeviceGroups, которая содержит 2 столбца, MachineID и GroupID. Вот пример

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

Мне нужно показать все MachineID, которые содержат GroupID A1 или A2, с отдельным столбцом, который даст Да / Нет, если этот 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

Ответы [ 4 ]

2 голосов
/ 10 апреля 2020

Вы можете использовать подзапрос

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 
0 голосов
/ 10 апреля 2020
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
0 голосов
/ 10 апреля 2020

Из того, что я беру, подзапрос выполнит работу:

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
0 голосов
/ 10 апреля 2020

Рассмотрим:

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, чтобы А1 или А2 видели. Остальное - условное агрегирование в предложении select.

...