SQL Запрос для поиска уникальных значений после где и GroupBy - PullRequest
1 голос
/ 15 января 2020

Использование AWS Афины для запроса таблицы aws_application.

В таблице есть такие вещи, как:

ID | Name 
server1  | Word 
server1  | Excel
server2  | Word 
server2  | Excel
server3  | Word 
server3  | Excel
server3  | Notepad 

Я ищу SQL Запрос, который может перечислить идентификаторы сервера (в этом примере), на котором не установлен «Блокнот». Результат должен показать.

ID
server1
server2

Я новичок в этом, и пока я могу только показать, на каком сервере есть блокнот. Я думал, что смогу как-то соединить таблицу с собой и вычесть, чтобы попытаться получить уникальные идентификаторы.

Вышеприведенный пример является обобщенным c, но его легче объяснить. Точно я могу выполнить следующее

select distinct resourceid
from aws_application
where name = 'Excel'
or name = 'Word'
group by resourceid

и получить в общей сложности 108 серверов.

Если я запускаю

select distinct resourceid
from aws_application
group by resourceid

, я получаю уникальный счет 116 Всего серверов. Я хочу вернуть число 8.

Конечно, здесь есть тысячи строк, так как каждая строка в таблице представляет отдельный exe-файл приложения, установленный на коробке.

Ответы [ 2 ]

1 голос
/ 15 января 2020

Вы можете использовать select distinct и not exists для фильтрации:

select distinct id
from mytable t
where not exists (select 1 from mytable t1 where t1.id = t.id and t1.name = 'Notepad')

Если вы хотите, чтобы количество идентификаторов, вы можете изменить select distinct id на select count(distinct id). Если вам нужны все записи, вы можете изменить их на select t.*

Другой вариант - использовать анти- left join:

select distinct t.id
from mytable t
left join mytable t1 on t1.id = t.id and t1.name = 'Notepad'
where t1.id is null
0 голосов
/ 15 января 2020

Я ищу SQL Запрос, который может сказать мне, на скольких серверах (в этом примере) НЕ установлен «Блокнот».

Вы можете использовать два уровня агрегации:

select count(*)
from (select id, sum(case when name = 'Notepad' then 1 else 0 end) as num_notepad
      from aws_application a
      group by id
     ) s
where num_notepad = 0;

Если вам нужен список, а не счет:

select id, 
from aws_application a
group by id
having sum(case when name = 'Notepad' then 1 else 0 end) = 0;

Более типично, однако, у вас будет таблица servers. Затем вы должны сделать:

select count(*)
from servers s
where not exists (select 1
                  from aws_application a
                  where a.userid = s.userid and
                        a.name = 'Notepad'
                 );

Или для списка используйте вместо него select s.*.

...