#sql
#sql
Вопрос:
У меня в базе данных есть такая таблица:
----------- ------- -------- --------------
| Person_ID | Month | Name | Special |
----------- ------- -------- --------------
| 807 | 01 | Smith | othercontent |
| 807 | 01 | Smith | othercontent |
| 807 | 02 | Smith | othercontent |
| 807 | 02 | Smith | othercontent |
| 807 | 02 | Smith | content |
| 807 | 02 | Smith | othercontent |
| 807 | 03 | Smith | othercontent |
| 807 | 03 | Smith | othercontent |
| 807 | 03 | Smith | othercontent |
| 807 | 04 | Smith | othercontent |
| 807 | 04 | Smith | content |
| 807 | 04 | Smith | othercontent |
| 981 | 01 | Walker | othercontent |
| 981 | 01 | Walker | othercontent |
| 981 | 02 | Walker | othercontent |
| 981 | 02 | Walker | othercontent |
| 981 | 02 | Walker | content |
| 981 | 02 | Walker | othercontent |
| 981 | 03 | Walker | othercontent |
| 981 | 03 | Walker | othercontent |
| 981 | 03 | Walker | othercontent |
| 981 | 04 | Walker | othercontent |
| 981 | 04 | Walker | content |
| 981 | 04 | Walker | othercontent |
----------- ------- -------- --------------
Я должен написать SQL-запрос, который выбирает каждый месяц, который не содержит «содержимого» хотя бы один раз.
И он должен выдавать только одну строку.
Итак, результат должен быть таким:
----------- ------- -------- --------------
| Person_ID | Month | Name | Special |
----------- ------- -------- --------------
| 807 | 01 | Smith | othercontent |
| 807 | 03 | Smith | othercontent |
| 981 | 01 | Walker | othercontent |
| 981 | 03 | Walker | othercontent |
----------- ------- -------- --------------
Как я могу выполнить это с помощью SQL-запроса?
Я пытался сделать это с помощью функции group by, но не смог заставить ее работать должным образом.
Ответ №1:
Если вам нужна только одна строка на человека / месяц, используйте агрегацию. Вы должны использовать having
предложение для фильтрации 'content'
строк:
select person_id, month, name, max(special)
from t
group by person_id, month, name
having sum(case when special = 'content' then 1 else 0 end) = 0;
Комментарии:
1. Этот запрос отлично работает с SQLite. Однако, если я попытаюсь использовать это в Excel (Данные -> «Из других источников» -> Из Microsoft Query) и выполнить SQL-запрос, я получу синтаксическую ошибку. Проблема , по — видимому , связана с частью , начинающейся с
having...
. Можете ли вы объяснить, что нужно изменить?2. @Robin . , , Это может быть потому
month
, что это зарезервированное слово ODB.3. Спасибо за подсказку, но это не сработает, даже если я изменю заголовок столбца на что-то другое. В выражении запроса все еще говорится о синтаксической ошибке (отсутствующий оператор)
'sum(case when special = 'content' then 1 else 0 end) = 0'
4. @Robin . , , Код является допустимым кодом SQL Server. Что такое базовая база данных?
5. это база данных SQLite, и ваш код SQL-запроса отлично работал в моем браузере базы данных. Для попытки запустить код в Excel я просто скопировал таблицу из своего исходного сообщения в an
.xlsx-file
и запустил процедуру, о которой я упоминал в предыдущем комментарии.
Ответ №2:
используйте это
select *
from t
where month not in ( select month from t as t2 where t2.special = 'content')
group by person_id, month, name, special
Ответ №3:
Я думаю, вам просто нужно
select distinct *
from t t1
where not exists(select 1 from t t2 where t1.month=t2.month and t2.special = 'content')