SQL IN 子句仅返回以逗号分隔的 ID 列表中第一个匹配项的行
SQL IN Clause only returning rows with first match in comma separated list of IDs
我有 5 个用户有一个列 'shop_access'(这是一个商店 ID 列表,例如:1,2,3,4)
我正在尝试从数据库中获取所有在 shop_access
中具有商店 ID(例如 2)的用户
Current Query:
SELECT * FROM users WHERE '2' IN (shop_access)
但是,只有 returns 个用户 shop_access 以数字 2 开头。
例如
- 用户 1 管理店铺 1,2,3
- 用户 2 管理商店 2,4,5
- 用户 3 管理商店 1,3,4
- 用户 4 管理商店 2,3
只有运行IN子句是User 2和User 4时才会返回
用户 1 被忽略(它不应该被忽略,因为它在列表中有编号 2)因为它没有 start 编号 2.
我目前无法返回并更改其设置方式,例如将其转换为 JSON 并先使用 PHP 进行处理,所以如果有人可以尝试使这项工作无需更改理想的列数据 (shop_access)。
table 的解决方案是使用 like
:
where concat(',', shop, ',') like '%,2,%'
或者如果要搜索的值作为参数给出:
where concat(',', shop, ',') like concat('%,', ?, ',%')
根据您的数据库,可能会有更简洁的选项可用。在 MuSQL 中:
where find_in_set('2', shop)
也就是说,我强烈建议修复您的数据模型。在数据库中存储 CSV 数据在很多方面都违背了关系数据库的目的。您应该有一个单独的 table 来存储 user/shop 关系,每个元组在单独的行中。推荐阅读:Is storing a delimited list in a database column really that bad?.
此外,您可能需要考虑在此处使用 REGEXP
作为选项:
SELECT *
FROM users
WHERE shop_access REGEXP '[[:<:]]2[[:>:]]';
-- [[:<:]] and [[:>:]] are word boundaries
SELECT * FROM users WHERE (shop_access = 2) OR (shop_access LIKE "2,%" OR shop_access LIKE "%,2,%" OR shop_access LIKE "%,2")
我有 5 个用户有一个列 'shop_access'(这是一个商店 ID 列表,例如:1,2,3,4)
我正在尝试从数据库中获取所有在 shop_access
中具有商店 ID(例如 2)的用户Current Query:
SELECT * FROM users WHERE '2' IN (shop_access)
但是,只有 returns 个用户 shop_access 以数字 2 开头。
例如
- 用户 1 管理店铺 1,2,3
- 用户 2 管理商店 2,4,5
- 用户 3 管理商店 1,3,4
- 用户 4 管理商店 2,3
只有运行IN子句是User 2和User 4时才会返回
用户 1 被忽略(它不应该被忽略,因为它在列表中有编号 2)因为它没有 start 编号 2.
我目前无法返回并更改其设置方式,例如将其转换为 JSON 并先使用 PHP 进行处理,所以如果有人可以尝试使这项工作无需更改理想的列数据 (shop_access)。
table 的解决方案是使用 like
:
where concat(',', shop, ',') like '%,2,%'
或者如果要搜索的值作为参数给出:
where concat(',', shop, ',') like concat('%,', ?, ',%')
根据您的数据库,可能会有更简洁的选项可用。在 MuSQL 中:
where find_in_set('2', shop)
也就是说,我强烈建议修复您的数据模型。在数据库中存储 CSV 数据在很多方面都违背了关系数据库的目的。您应该有一个单独的 table 来存储 user/shop 关系,每个元组在单独的行中。推荐阅读:Is storing a delimited list in a database column really that bad?.
此外,您可能需要考虑在此处使用 REGEXP
作为选项:
SELECT *
FROM users
WHERE shop_access REGEXP '[[:<:]]2[[:>:]]';
-- [[:<:]] and [[:>:]] are word boundaries
SELECT * FROM users WHERE (shop_access = 2) OR (shop_access LIKE "2,%" OR shop_access LIKE "%,2,%" OR shop_access LIKE "%,2")