如果任何行中的字段X的值为Y,则忽略MySQL中GROUP BY的else组结果,而无需子查询

时间:2018-10-20 15:36:02

标签: mysql group-by left-join

我有两个表:

用户

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 中没有任何条目的用户。在状态表中使用group by子句来使strong>状态成功。 我的预期结果是:

结果:

 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 :(得分:1)

您应该将成功条件从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子句中指定既不按表达式分组也不在功能上依赖于表达式分组或聚集的列是非标准的。

最好以某种方式汇总状态(选择最适合您的需求:minmax,...):

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

答案 1 :(得分:0)

尝试下一个查询。我们首先将您在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