если поле X в какой-либо строке имеет значение Y, тогда игнорировать результаты других групп по GROUP BY в mysql без подзапроса - PullRequest
0 голосов
/ 20 октября 2018

У меня есть две таблицы:

пользователи

id |  admin_id   | name
 -----------------------
  1 |    10       | a
  2 |    10       | b
  3 |    15       | c
  4 |    10       | d
  5 |    10       | e
  6 |    10       | f

статус

 id |  user_id    | status
 -----------------------
  1 |     2       | error
  2 |     2       | success
  3 |     2       | error
  4 |     4       | success
  5 |     6       | error

сейчас я пытаюсь получить всех пользователей admin_id 10 которые не имеют записей в таблице status и пользователи, у которых нет записей с status success в таблице состояния с помощью предложения group by.Мои ожидаемые результаты:

Результат:

 id |  admin_id   | name  |  status
 ------------------------------------
  1 |     10      |   a   |  null
  5 |     10      |   e   |  null
  6 |     10      |   f   |  error

Таким образом, согласно ожидаемым результатам, запрос должен игнорировать user_id 2,4, потому что эти два имеют статус успеха в таблице состояния.Прямо сейчас я пытаюсь сделать запрос следующим образом:

SELECT
    users.*,
    status.status
FROM
    users
LEFT JOIN
    status ON users.id = status.user_id
WHERE
    users.admin_id = 10 AND status.status != "success"
GROUP BY
    users.id

Это может быть сделано подзапросом, но мое требование состоит в том, чтобы сделать это с одним запросом и без использования подзапроса.

Есть ли способ сделать это?
Спасибо!

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Вы должны переместить условие успеха из предложения where в предложение join ... on:

SELECT
    users.*,
    status.status
FROM
    users
LEFT JOIN
    status ON users.id = status.user_id AND status.status != "success"
WHERE
    users.admin_id = 10 
GROUP BY
    users.id

Примечание, не связанное с вашим вопросом: для SQL это нестандартно, указывать столбцыв вашем предложении select, которые не сгруппированы, не функционально не зависят от сгруппированных по выражению и не агрегированы.

Так что лучше каким-то образом агрегировать статус (выберите то, что лучше всего соответствует вашим потребностям: min, max, ...):

SELECT
    users.*,
    min(status.status) as status
FROM
    users
LEFT JOIN
    status ON users.id = status.user_id AND status.status != "success"
WHERE
    users.admin_id = 10 
GROUP BY
    users.id
0 голосов
/ 20 октября 2018

Попробуйте следующий запрос.Сначала мы группируем столбцы пользователей, которые вы используете в предложении SELECT, затем мы используем предложение HAVING для отбрасывания тех групп, чье число status = "success" больше нуля.

SELECT
    users.id,
    users.admin_id,
    users.name,
    MAX(status.status)
FROM
    users
LEFT JOIN
    status ON status.user_id = users.id
WHERE
    users.admin_id = 10
GROUP BY
    users.id, users.admin_id, users.name
HAVING
    SUM(CASE WHEN status.status = "success" THEN 1 ELSE 0 END) = 0
...