从列中的逗号收集的ID中选择行

时间:2018-07-13 14:58:51

标签: mysql sql rel

我的数据库是:

# 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
    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,%"
    )

此查询仅返回一个项目。如何通过一个查询获取每个项目?

3 个答案:

答案 0 :(得分:3)

有很多原因不将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是一个起点。

答案 1 :(得分:1)

首先,如上所述,请重新设计桌子。 但是,如果做不到,那么完成这项工作的方法就是在查询中添加更多逗号- 即添加前导和尾部逗号来满足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' + ',%' 

    )

答案 2 :(得分:0)

这有点棘手,但并非不可能,也不是无知的迹象:

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”必须是您数据库中从未找到的任何值。