【问题标题】:MySql Group Concat - Don't want rows excluded from Where clauseMySql Group Concat - 不希望从 Where 子句中排除行
【发布时间】:2015-08-17 20:16:36
【问题描述】:

好的,所以我有一个案例,我想做一个 Group Concat,但也使用 Group Concat 中的同一列作为语句中的 Where 子句,但 不排除由于 Where 导致 Group Concat。知道了?哈哈哈我的意思是:

SELECT posts.id, post.post_date, 
  GROUP_CONCAT(DISTINCT terms.name ORDER BY terms.name DESC SEPARATOR ';')
FROM posts
INNER JOIN terms on terms.post_id = posts.id
WHERE terms.name = "kittens";

所以我想获取帖子的terms.name =“kittens”的帖子,但是帖子可以有多个terms.name,例如“kittens”、“cats”、“cuteness”等。所以在Group Concat 我希望结果是“kittens;cats;cuteness”(每一个都是与posts.id相关的单独条目)。但是,在 Where 子句中使用“kittens”时,所有 Group Concat 返回的是“kittens”。

如果我说“WHERE terms.name = 'kittens' OR terms.name = 'cats'”,Concat 组返回“kittens;cats”...但我只想搜索一个 terms.name 和获取 Group Concat 中的其余条款。

我该如何解决这个问题?

【问题讨论】:

  • 使组在选择中连接一个子查询
  • GROUP_CONCAT() 函数需要查询中缺少的 GROUP BY 子句。这使得 MySQL 从所有选定的行中创建一个组。因为它们没有出现在GROUP BY 子句中,所以为posts.idpost.post_date 返回的值是来自相应列的一些随机值。
  • @axiac 对不起,这是一个巨大查询的截断版本,只是为了重点关注这一点而忽略了它

标签: mysql group-concat


【解决方案1】:

使用Having 代替Where。但是您还需要在这样的选择子句中包含terms.name

SELECT posts.id, post.post_date, terms.name,
  GROUP_CONCAT(DISTINCT terms.name ORDER BY terms.name DESC SEPARATOR ';')
FROM posts
INNER JOIN terms on terms.post_id = posts.id
HAVING terms.name = "kittens";

【讨论】:

  • 这更近了一步,谢谢!由于某种原因,结果被省略了,我可能会尝试 find_in_set 并检查 group_concat 本身
  • 它可以和HAVING terms.name LIKE '%kittens%'一起工作,但是这样它就像蜗牛一样慢,因为(至少)两个原因:1)缺少WHERE子句迫使MySQL计算笛卡尔积两张桌子,这可能是巨大的; 2) LIKE 即使对于索引列也很慢,更不用说在这里它对计算值进行操作(即不涉及索引,也无法优化它)。
【解决方案2】:

您需要的查询是:

SELECT p.id, p.post_date,
    GROUP_CONCAT(DISTINCT t.name ORDER BY t.name DESC SEPARATOR ';')
FROM posts p
  INNER JOIN terms s ON s.post_id = p.id       # "s" from "search"
  INNER JOIN terms t ON t.post_id = p.id
WHERE s.name = "kittens"                     
GROUP BY p.id

工作原理

如果我对问题的理解正确,您需要选择帖子中包含“小猫”一词的所有词。它需要加入表格terms 两次:一次获取所有包含“小猫”一词的帖子,再次获取以这种方式选择的帖子的条款。

这就是查询的作用:它将表posts 别名为“p”(“p”来自“post”)与表terms 别名为“s”(“s”来自“搜索”)并仅选择“term”为“kittens”的对(post,term)。然后它再次以“t”(“t”来自“term”)的形式加入表terms,并将具有术语“kittens”的帖子与其所有术语匹配。

GROUP BY 子句从具有相同posts.id 的所有行中创建一个组。由于id 是表postsPK,因此无需在GROUP BY 子句中添加posts.post_datep.post_datefunctionally dependent on p.id

【讨论】:

  • 嗯,我明白你的意思了,但不幸的是,添加第二个连接似乎没有帮助......
  • 我认为问题在于术语之前有多个连接。我认为解决方案是这种情况是使用更好的数据模型 XD
猜你喜欢
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
  • 2017-04-19
  • 1970-01-01
  • 2012-01-31
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多