SQL 使用 LIKE 子查询进行查询
SQL query with LIKE subquery
我有一个名为 Groups
的 table,如下所示。
+---------+--------------------------------+
| GroupID | GroupMembers |
+---------+--------------------------------+
| 1 | 2342342;234234;234235;3533453; |
+---------+--------------------------------+
| 2 | 345345345;345345353;345335334; |
+---------+--------------------------------+
GroupMembers
字段是由分号分隔的用户 ID 列表。
我有另一个名为 UserRecord
的 table,用于存储用户 ID 和其他详细信息。
我需要一个 SQL 查询来获取用户 ID 的 md5 校验和并找出它在哪个组中。
我试过以下语句,它只返回所有 GroupID 的列表,而不仅仅是用户所在的组。
SELECT g.GroupID FROM Groups g WHERE g.GroupMembers LIKE '%' || (SELECT UID FROM UserRecord ur WHERE md5(ur.UID) = ' \*md5 checksum*\ ') || '%'
我也摆弄过 INNER JOIN
和 WHERE EXISTS
但没有取得任何进展。
如果可能,您应该更改数据库架构。一般来说,在关系数据库中存储逗号分隔的列表是不好的。
但是,如果这不是一个选项,请尝试使用 join
:
select g.GroupID
from Groups g
join UserRecord ur on ';' || g.groupmembers like '%;' || ur.mqid || ';%'
where md5(ur.UID) = ' \*md5 checksum*\ '
我确实认为数据库实际上应该重组,但已经说过了。
在你的情况下,我相信以下最接近你的查询,我相信这将解决你的问题:
SELECT g.GroupID FROM Groups g
WHERE g.GroupMembers LIKE '%;' || (SELECT UID FROM UserRecord ur WHERE md5(ur.UID) = ' \*md5 checksum*\ ') || ';%'
OR g.GroupMembers LIKE (SELECT UID FROM UserRecord ur WHERE md5(ur.UID) = ' \*md5 checksum*\ ') || ';%'
您的语句检查字符串中某处是否存在 ID,因此如果您要查找 ID 2,您还会找到具有 12、23, 2222 等。通过此修改,您将只会找到具有 ;ID; 的组。或以 ID 开头;这样只会找到完整的 ID 匹配项。
我非常非常非常同意正确的解决方案是 GroupMembers
table 每个组和该组中的成员一行。我也生活在现实世界中,所以知道我们有时会被其他人糟糕的设计决策所困(或者,也许决策是好的……出于另一个目的)。
MySQL 中正确的语法是:
select g.GroupID
from Groups g join
UserRecord ur
on concat(';', g.groupmembers) like concat('%;', ur.mqid, ';%')
where md5(ur.UID) = ' \*md5 checksum*\ ';
默认情况下,在 MySQL 中,||
运算符是逻辑运算符 OR
。它只是测试相邻的值是否为 0。
您还可以将 on
条件表示为:
on find_in_set(ur.mqid, replace(g.groupmember, ';', ',')) > 0;
我有一个名为 Groups
的 table,如下所示。
+---------+--------------------------------+
| GroupID | GroupMembers |
+---------+--------------------------------+
| 1 | 2342342;234234;234235;3533453; |
+---------+--------------------------------+
| 2 | 345345345;345345353;345335334; |
+---------+--------------------------------+
GroupMembers
字段是由分号分隔的用户 ID 列表。
我有另一个名为 UserRecord
的 table,用于存储用户 ID 和其他详细信息。
我需要一个 SQL 查询来获取用户 ID 的 md5 校验和并找出它在哪个组中。
我试过以下语句,它只返回所有 GroupID 的列表,而不仅仅是用户所在的组。
SELECT g.GroupID FROM Groups g WHERE g.GroupMembers LIKE '%' || (SELECT UID FROM UserRecord ur WHERE md5(ur.UID) = ' \*md5 checksum*\ ') || '%'
我也摆弄过 INNER JOIN
和 WHERE EXISTS
但没有取得任何进展。
如果可能,您应该更改数据库架构。一般来说,在关系数据库中存储逗号分隔的列表是不好的。
但是,如果这不是一个选项,请尝试使用 join
:
select g.GroupID
from Groups g
join UserRecord ur on ';' || g.groupmembers like '%;' || ur.mqid || ';%'
where md5(ur.UID) = ' \*md5 checksum*\ '
我确实认为数据库实际上应该重组,但已经说过了。
在你的情况下,我相信以下最接近你的查询,我相信这将解决你的问题:
SELECT g.GroupID FROM Groups g
WHERE g.GroupMembers LIKE '%;' || (SELECT UID FROM UserRecord ur WHERE md5(ur.UID) = ' \*md5 checksum*\ ') || ';%'
OR g.GroupMembers LIKE (SELECT UID FROM UserRecord ur WHERE md5(ur.UID) = ' \*md5 checksum*\ ') || ';%'
您的语句检查字符串中某处是否存在 ID,因此如果您要查找 ID 2,您还会找到具有 12、23, 2222 等。通过此修改,您将只会找到具有 ;ID; 的组。或以 ID 开头;这样只会找到完整的 ID 匹配项。
我非常非常非常同意正确的解决方案是 GroupMembers
table 每个组和该组中的成员一行。我也生活在现实世界中,所以知道我们有时会被其他人糟糕的设计决策所困(或者,也许决策是好的……出于另一个目的)。
MySQL 中正确的语法是:
select g.GroupID
from Groups g join
UserRecord ur
on concat(';', g.groupmembers) like concat('%;', ur.mqid, ';%')
where md5(ur.UID) = ' \*md5 checksum*\ ';
默认情况下,在 MySQL 中,||
运算符是逻辑运算符 OR
。它只是测试相邻的值是否为 0。
您还可以将 on
条件表示为:
on find_in_set(ur.mqid, replace(g.groupmember, ';', ',')) > 0;