【问题标题】:SQL Many to Many Query Find All Multiple Matches Duplicate IssueSQL多对多查询查找所有多个匹配重复问题
【发布时间】:2012-10-10 01:06:26
【问题描述】:

我一直在使用这样的 JPQL 查询:

SELECT s 
FROM Sentence s
INNER JOIN s.words sw
WHERE s.date = :date
AND sw IN (:words)
GROUP BY s
HAVING count(sw) = :numberOfWords

在 SQL 中,s.words 将是多对多中的链接表 :word 是我们要匹配的单词的集合 :numberOfWords 是集合中的单词数

对于那些不熟悉 JPQL 的人,类似的 SQL 可以在这里找到: SQL query to find matches for multiple criteria

我遇到了问题,不知道是设计问题还是查询问题。

所以我有句子 (s) 和单词 (w),而 sentence_word (sw) 表将两者连接起来。例如句子“Thelead dog of the group is blue”和[ the , cat ]的词集合,这个查询将选择这个句子作为匹配。这是一个误报,因为它包含两次“the”并且不包含“cat”。

在 SQL 中,我认为它是:

SELECT s.id
FROM sentence s
JOIN sentence_word sw ON ( sw.s_id = s.id )
JOIN word w ON ( w.id = sw.w_id )
WHERE w.word IN ( 'the', 'cat' )
GROUP BY s.id
HAVING COUNT(1) = 2

我能想到的最简单的解决方案是在链接表中禁止重复,因此这个句子中的链接不是两个链接,而是只有一个(因此链接表存储该句子包含单词 the,而不是多少次)。但是,我认为有时我会想要多次搜索包含“the”的句子,所以我不想使用这个选项。

请帮忙!

资源

可以在这里找到一些类似搜索和性能的好例子(感谢链接的回答者):How to filter SQL results in a has-many-through relation

【问题讨论】:

  • 只要找到列表中的任何个单词,“IN”子句就会匹配。您需要找到一种方法来确保找到所有个单词。

标签: mysql sql jpql


【解决方案1】:

更改HAVING 子句以计算不同的单词,使用COUNT(DISTINCT sw.w_id) = 2COUNT(DISTINCT w.word) = 2

SELECT s.id
FROM sentence s
JOIN sentence_word sw ON ( sw.s_id = s.id )
JOIN word w ON ( w.id = sw.w_id )
WHERE w.word IN ( 'the', 'cat' )
GROUP BY s.id
HAVING COUNT(DISTINCT sw.w_id) = 2 ;

【讨论】:

  • 经过快速测试,这似乎在 SQL 中可以正常工作,谢谢!我通常会尽量避免不同,甚至没有想过拥有它。我将继续在更大的数据集上进行测试,然后接受。性能似乎也相当不错。
  • 关于性能,您应该检查执行 (EXPLAIN) 计划和您拥有的索引。您还可以尝试对查询进行其他重写。看到这个问题:How to filter SQL results in a has-many-through relation 有超过 10 个版本来解决同一个问题(在你的情况下,它们必须稍微改变,因为你对 (s_id, w_id) 组合没有唯一的约束)。
  • 联接通常性能更好,但需要动态 SQL。 “通用”解决方案(如您的)更容易编写,并且可以使用可以是表格的可变参数列表。
  • 谢谢,是的,我看到了其他链接,它很棒。我真的在寻找一种方法来避免编写大量子查询并在此处添加 distinct 效果很好。我可能会牺牲一些 sql 性能来换取没有一堆循环创建子查询。非常感谢您的帮助!
猜你喜欢
  • 2022-10-07
  • 1970-01-01
  • 2020-06-08
  • 2011-08-08
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
相关资源
最近更新 更多