我有以下MySQL查询。
SELECT
login,
firstname,
lastname,
email
FROM
xcart_customers
WHERE
login LIKE 'anonymous%'
AND email NOT IN (
SELECT
email
FROM
xcart_customers AS cx
WHERE
cx.login NOT LIKE 'anonymous%'
)
GROUP BY
email;
基本上有两组客户,具有登录名的客户和匿名客户,他们都以"anonymous%"的登录名开头。
我正在尝试从列表中删除与匿名用户具有相同电子邮件地址的非匿名用户。
我以为上面的查询会起作用,但我仍然得到一些与非匿名用户匹配的电子邮件地址。
login | firstname | lastname | email
---------------------------------------------------------------------------
anonymous-10 | Eric | Byorn | byorn@mail.com
---------------------------------------------------------------------------
some_user_name | Eric | Byorn | byorn@mail.com
---------------------------------------------------------------------------
所以我正在尝试解决所有匿名用户,他们只出现在匿名结果中。
最有效且恕我直言,最优雅的解决方案是使用外部连接:
SELECT
a.login,
a.firstname,
a.lastname,
a.email
FROM xcart_customers a
LEFT JOIN xcart_customers b ON b.email = a.email
AND b.login NOT LIKE 'anonymous%'
WHERE a.login LIKE 'anonymous%'
AND b.email IS NULL
这里有两个关键技巧:
- 由于缺少的左连接将返回左连接表中的所有 NULL,因此 WHERE 子句将排除具有匹配项的行 连接
- 表上的所有条件(甚至是非键)都必须在连接条件中,即不在 WHERE 子句中,否则才能有效地将外部连接转换为内部连接
请注意,您对GROUP BY
的使用既有缺陷又没有必要。