【问题标题】:WHERE IN with subquery NOT WORKING as expectedWHERE IN 子查询不按预期工作
【发布时间】:2014-08-03 22:59:11
【问题描述】:

我正在尝试使用我创建的父路径从我的类别表中获取结果。 当我使用手动数据启动请求时,它运行良好。 当我使用子查询动态尝试相同的请求时,我只得到一个结果而不是预期的 4 个。 我不明白为什么,你能帮帮我吗?

http://sqlfiddle.com/#!2/88b68/6

/*Working query*/
SELECT t.id_categorie FROM t 
WHERE t.id_categorie IN (1396,1399,1403,1412)

/*Not working by subquery ??*/
SELECT cat.id_categorie FROM t as cat
WHERE 
cat.id_categorie IN (SELECT REPLACE(t.path,'.',',') FROM t WHERE t.id_categorie = 1412)

提前致谢,

问候,

【问题讨论】:

  • 这是因为t.pathvarchar 列,而不是INT
  • 请参阅 FIND_IN_SET(),尽管此类问题可能是设计不佳的症状。也就是说,物化路径是一种公认​​的策略。

标签: mysql sql subquery where-in in-subquery


【解决方案1】:

这不起作用的原因是您的内部 SELECT 生成一个以逗号分隔的 VARCHAR,而不是四个单独的整数。

在 MySQL 中你可以使用find_in_set,像这样:

SELECT cat.id_categorie FROM t as cat
WHERE find_in_set(cat.id_categorie, (
  SELECT REPLACE(t.path,'.',',')
  FROM t WHERE t.id_categorie = 1412))

我所做的是将查询中的 IN 表达式替换为对 find_in_set 的调用,而其他一切都保持不变。

Demo

但是,此解决方案存在根本缺陷,因为它将多个值存储在单个列中以表示多对多关系。实现此要求的更好方法是使用单独的表,将表中的行与其相关行连接起来。

【讨论】:

  • 谢谢我明白 :-) 我使用这个解决方案来获取面包屑而不是递归查询,你能解释一下建议的更好做法吗?
  • @user3384179 如果我正确理解您想要实现的目标,请查看answers to this question,他们展示了如何在 MySQL 中实现自我关系。
【解决方案2】:

in 与逗号分隔的列表一起使用不会达到您想要的效果。即使您使用子查询。你可以试试这个:

SELECT cat.id_categorie
FROM t cat
WHERE EXISTS (SELECT 1
              FROM t
              WHERE t.id_categorie = 1412 AND
                    find_in_set(cat.id_categorie, REPLACE(t.path, '.', ',')) > 0
             );

我不确定您的数据是什么样子,甚至不确定该查询应该做什么(子查询与外部查询在同一个表上似乎很奇怪)。但是,通常,您希望将内容存储在表中而不是分隔列表中。你看,SQL 有一个内置的列表数据结构。它被称为表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多