Как написать этот MySQL Query? - PullRequest
2 голосов
/ 13 июня 2011

Предположим, у нас есть таблица Users, которая имеет только один столбец UserId, который является первичным ключом.

У нас есть вторая таблица Events, которая имеет три столбца, EventId, UserId и Status.A Status - это BOOL NOT NULL.UserId проиндексирован, но не уникален.

Таблица Status имеет ограничение внешнего ключа UserId для Users.UserId.

Теперь я хочу запросить все UserId sдля которого нет строки в Events такой, что Event.Status = TRUE.Есть ли способ сделать это с JOIN?(Только один оператор предпочтителен)

Например:

Users
--------
1
2
3

Events
--------
EventId   UserId  Status
1         1       FALSE
2         1       TRUE
3         2       FALSE
4         2       FALSE

Тогда запрос, который я ищу, должен вернуть:

UserId
-------
2
3

Спасибо!

Ответы [ 2 ]

3 голосов
/ 13 июня 2011

Удивительно, но подвыбор является достаточно эффективным способом сделать это на MySQL. Итак:

SELECT UserId
FROM   Users
WHERE  UserId NOT IN (
       SELECT DISTINCT UserID
       FROM   Events
       WHERE  Status = TRUE
       )

Обратите внимание, что я использую DISTINCT там, что может не подходить для указанной статьи. Имейте в виду, что вы можете быть в порядке с DISTINCT или с его отключением (но я не знаю, приведет ли это к проблемному промежуточному набору данных, или MySQL умен).

Или вы можете сделать версию LEFT JOIN / IS NULL, которая не имеет проблемы DISTINCT:

SELECT    Users.UserId
FROM      Users
LEFT JOIN Events
          ON Events.UserId = Users.UserId AND Events.Status = TRUE
WHERE     Events.UserId IS NULL

См. Ссылку выше для обсуждения, но MySQL обеспечивает в основном одинаковую производительность в обоих случаях (тогда как использование NOT EXISTS вместо NOT IN было бы заметно менее эффективным).

Я бы попробовал оба (или все три, если вы попробуете как с, так и без DISTINCT на первом) и посмотрел бы, что лучше всего работает с вашими реальными данными.

2 голосов
/ 13 июня 2011

Примерно так:

select UserId
from Users
where UserId not in (
    select UserId 
    from Events 
    where Status = TRUE)

с левым соединением:

select UserId
from Users usr
    left join Events evt on
        evt.UserId = usr.UserId and evt.Status = TRUE
where evt.UserId is null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...