Select 行来自逗号收集的列中的 ID
Select rows from comma collected ids in a column
我的数据库是:
# item_rel
id | item_ids
--------------------------
1 | 1,2,4,6,8,10
2 | 3,5,7
3 | 9,11,12
.. | ............
# items
id | name
--------------------------
1 | Lorem
2 | Ipsum
3 | Sed
4 | Amed
.. | ............
问题是 select 项查询。我尝试了很多方法但没有运气。只有这个接近预期结果:
SELECT
items.*
FROM
items
WHERE
items.id IN (
SELECT
items_rel.ids
FROM
items_rel
WHERE
items_rel.ids LIKE "1" OR
items_rel.ids LIKE "1,%" OR
items_rel.ids LIKE "%,1" OR
items_rel.ids LIKE "%,1,%"
)
这个查询returns只有一个项目..如何用一个查询得到每一个项目?
不将 ID 存储在逗号分隔列表中的原因有很多很多:
- 应使用适当的类型存储值。数字不应存储为字符串。
- 应正确声明外键。您不能声明外键关系。
- SQL 表传统上每列有一个值,而不是可变数字。
- SQL 字符串处理能力很差。
- 对此类结构的查询无法轻松使用索引。
- SQL 有一个非常好的存储列表的数据结构。它被称为
table
.
有时,我们会被其他人的非常、非常、非常、非常、非常、非常糟糕的决定所困。
MySQL 抵消一个名为 find_in_set()
:
的解决方法
SELECT i.*
FROM items i JOIN
items_rel ir
ON find_in_set(i.id, ir.ids) > 0;
但是,您应该努力修复数据模型,而不是让查询正常工作。 Wikipedia 是一个起点。
首先,如上所述,请重新设计表格。
但是,如果不能,使这项工作起作用的方法是在查询中添加更多逗号——
即添加前导和尾随逗号以满足 Where...LIKE...
SELECT
Rows_items.*
FROM
Rows_items
WHERE
Rows_items.id IN (
SELECT
Rows_item_rel.id
FROM
Rows_item_rel
WHERE
',' + Rows_item_rel.item_ids + ',' LIKE '%,' + '1' + ',%'
)
这有点棘手,但并非不可能,也不是无知的表现:
SET @ids = (SELECT ids FROM item_rel
WHERE ids LIKE '1' OR ids LIKE '1,%' OR ids LIKE '%,1' OR ids LIKE '%,1,%') ;
SET @ids = (SELECT IF (@ids IS NOT NULL,@ids,'99999999999999999999999')) ;
SET @q = CONCAT('SELECT * FROM items WHERE ID IN (', @ids,')') ;
PREPARE stmt FROM @q ;
EXECUTE stmt ;
“99999999999999999999999”必须是在您的数据库中从未找到的任何值。
我的数据库是:
# item_rel
id | item_ids
--------------------------
1 | 1,2,4,6,8,10
2 | 3,5,7
3 | 9,11,12
.. | ............
# items
id | name
--------------------------
1 | Lorem
2 | Ipsum
3 | Sed
4 | Amed
.. | ............
问题是 select 项查询。我尝试了很多方法但没有运气。只有这个接近预期结果:
SELECT
items.*
FROM
items
WHERE
items.id IN (
SELECT
items_rel.ids
FROM
items_rel
WHERE
items_rel.ids LIKE "1" OR
items_rel.ids LIKE "1,%" OR
items_rel.ids LIKE "%,1" OR
items_rel.ids LIKE "%,1,%"
)
这个查询returns只有一个项目..如何用一个查询得到每一个项目?
不将 ID 存储在逗号分隔列表中的原因有很多很多:
- 应使用适当的类型存储值。数字不应存储为字符串。
- 应正确声明外键。您不能声明外键关系。
- SQL 表传统上每列有一个值,而不是可变数字。
- SQL 字符串处理能力很差。
- 对此类结构的查询无法轻松使用索引。
- SQL 有一个非常好的存储列表的数据结构。它被称为
table
.
有时,我们会被其他人的非常、非常、非常、非常、非常、非常糟糕的决定所困。
MySQL 抵消一个名为 find_in_set()
:
SELECT i.*
FROM items i JOIN
items_rel ir
ON find_in_set(i.id, ir.ids) > 0;
但是,您应该努力修复数据模型,而不是让查询正常工作。 Wikipedia 是一个起点。
首先,如上所述,请重新设计表格。 但是,如果不能,使这项工作起作用的方法是在查询中添加更多逗号—— 即添加前导和尾随逗号以满足 Where...LIKE...
SELECT
Rows_items.*
FROM
Rows_items
WHERE
Rows_items.id IN (
SELECT
Rows_item_rel.id
FROM
Rows_item_rel
WHERE
',' + Rows_item_rel.item_ids + ',' LIKE '%,' + '1' + ',%'
)
这有点棘手,但并非不可能,也不是无知的表现:
SET @ids = (SELECT ids FROM item_rel
WHERE ids LIKE '1' OR ids LIKE '1,%' OR ids LIKE '%,1' OR ids LIKE '%,1,%') ;
SET @ids = (SELECT IF (@ids IS NOT NULL,@ids,'99999999999999999999999')) ;
SET @q = CONCAT('SELECT * FROM items WHERE ID IN (', @ids,')') ;
PREPARE stmt FROM @q ;
EXECUTE stmt ;
“99999999999999999999999”必须是在您的数据库中从未找到的任何值。