#sql #sql-server
Вопрос:
У меня есть 2 стола:
Таблица устройств
---------- ----------
| DeviceId | Name |
---------- ----------
| 10| Dev10 |
| 20| Dev20 |
| 30| Dev30 |
---------- ----------
Таблица истории
---------- ------- ---------------------
| DeviceId | State | TimeStamp |
---------- ------- ---------------------
| 10| 0 | 06/09/2021 11:10:01 |
| 20| 1 | 06/09/2021 11:10:02 |
| 30| 0 | 06/09/2021 11:10:03 |
| 10| 0 | 06/09/2021 11:10:04 |
| 20| 0 | 06/09/2021 11:10:05 |
| 30| 1 | 06/09/2021 11:10:05 |
| 10| 2 | 06/09/2021 11:10:06 |
| 20| 0 | 06/09/2021 11:10:06 |
| 30| 0 | 06/09/2021 11:10:06 |
---------- ------- ---------------------
Я могу выбрать идентификаторы устройств, которые когда-либо были в состоянии=2
SELECT *
FROM Device A
CROSS APPLY (SELECT TOP 1 *
FROM History B
WHERE A.ID = B.DeviceId and B.[State]=2
ORDER BY B.TimeStamp DESC) as B
order by A.Id
Вопрос в том, как выбрать устройства, которые никогда не были в состоянии=2.
Результат должен быть:
---------- ----------
| DeviceId | Name |
---------- ----------
| 20| Dev20 |
| 30| Dev30 |
---------- ----------
Комментарии:
1.
where not exists (select * from history where deviceID = a.deviceId and state = 2)
. Хотя обычно я предпочитаю что-то вродеleft join History h on h.deviceId = a.deviceId and h.state = 2 where h.deviceId is null
Ответ №1:
Вы хотите знать, чего не существует, естественный синтаксис заключается в использовании exists
select *
from Device d
where not exists (
select *
from History h
where h.DeviceId = d.DeviceId and h.state = 2
)