SQL IN 子句仅返回以逗号分隔的 ID 列表中具有第一个匹配项的行
Posted
技术标签:
【中文标题】SQL IN 子句仅返回以逗号分隔的 ID 列表中具有第一个匹配项的行【英文标题】:SQL IN Clause only returning rows with first match in comma separated list of IDs 【发布时间】:2020-12-31 22:30:15 【问题描述】:我有 5 个用户,他们有一列“shop_access”(这是商店 ID 的列表,例如:1、2、3、4)
我正在尝试从数据库中获取所有在其 shop_access 中具有商店 ID(例如 2)的用户
Current Query:
SELECT * FROM users WHERE '2' IN (shop_access)
但是,它只返回 shop_access 以数字 2 开头的用户。
例如
用户 1 管理店铺 1,2,3 用户 2 管理店铺 2,4,5 用户 3 管理店铺 1,3,4 用户 4 管理商店 2,3运行 IN 子句时将返回的唯一一个是用户 2 和用户 4。
用户 1 被忽略(它不应该因为它在列表中有数字 2),因为它不是以数字 2开始。
我目前无法返回并更改设置方式,例如将其转换为 JSON 并首先使用 php 处理它,因此如果有人可以尝试使其工作而无需更改列理想的数据(shop_access)。
【问题讨论】:
请用您正在运行的数据库标记您的问题:mysql、oracle、postgresql...? 您能否更改查询以对用户和商店访问表 WHERE shopid = 2 进行联接? 【参考方案1】:一个可移植的解决方案是使用like
:
where concat(',', shop, ',') like '%,2,%'
或者如果要搜索的值作为参数给出:
where concat(',', shop, ',') like concat('%,', ?, ',%')
根据您的数据库,可能会有更简洁的选项可用。在 MuSQL 中:
where find_in_set('2', shop)
也就是说,我强烈建议您修复您的数据模型。在数据库中存储 CSV 数据在许多方面违背了关系数据库的目的。您应该有一个单独的表来存储用户/商店关系,每个元组在单独的行上。推荐阅读:Is storing a delimited list in a database column really that bad?。
【讨论】:
LIKE '%2%' 应该在您的第一个示例中发挥作用。百分号也会检查空字符串。 @CaptainKenpachi '%2%' 不会成功,因为它也会匹配 12,22,242,... 我不认为这是有意的【参考方案2】:另外,您可能需要考虑在此处使用REGEXP
作为选项:
SELECT *
FROM users
WHERE shop_access REGEXP '[[:<:]]2[[:>:]]';
-- [[:<:]] and [[:>:]] are word boundaries
【讨论】:
【参考方案3】:SELECT * FROM users WHERE (shop_access = 2) OR (shop_access LIKE "2,%" OR shop_access LIKE "%,2,%" OR shop_access LIKE "%,2")
【讨论】:
尝试在你的答案中加入一点描述/上下文/推理,会更有帮助。以上是关于SQL IN 子句仅返回以逗号分隔的 ID 列表中具有第一个匹配项的行的主要内容,如果未能解决你的问题,请参考以下文章