SQL n:n - 联结表中查询的最佳实践
Posted
技术标签:
【中文标题】SQL n:n - 联结表中查询的最佳实践【英文标题】:SQL n:n - best practice for queries in junction table 【发布时间】:2014-02-18 23:11:47 【问题描述】:我知道已经针对 SQL n:n 查询提出了许多问题。但是我找不到我的问题的解决方案。
我想创建一个类似于个人词库的项目。在其中,用户可以定义哪个单词与其他单词相关。我有两张桌子:
words:
+----+-----------+
| id | word |
+----+-----------+
| 1 | house |
| 2 | residence |
+----+-----------+
words_2_words (junction table)
+----+-------+-------+
| id | word1 | word2 |
+----+-------+-------+
| 1 | 1 | 2 |
+----+-------+-------+
查找 house 的所有同义词相当容易:
SELECT * FROM words_2_words WHERE word1 = 1;
但是,为了确保,我还找到了仅在“word2”列中列出的单词,我实际上需要 2 个查询:
SELECT *, word2 AS synonym FROM words_2_words WHERE word1 = 1;
SELECT *, word1 AS synonym FROM words_2_words WHERE word2 = 1;
如何将这 2 个查询放在一个查询中以获得更快的结果?
【问题讨论】:
【参考方案1】:你可以使用IN
:
SELECT CASE WHEN Word1 = 1 THEN Word2 ELSE Word1 END AS Word
FROM words_2_words
WHERE 1 IN (Word1, Word2):
或联合:
SELECT Word2 AS Word
FROM words_2_words
WHERE Word1 = 1
UNION [ALL]
SELECT Word1
FROM words_2_words
WHERE Word2 = 1;
添加或删除[ALL]
,具体取决于您是否想要不同的结果。
要恢复实际的话,我建议只加入两次,然后你可以把两个词都说出来:
SELECT CASE WHEN w2w.Word1 = $id THEN w2.Word ELSE w1.Word END AS Word
FROM words_2_words w2w
INNER JOIN words w1
ON w2w.word1 = w1.id
INNER JOIN words w2
ON w2w.word2 = w2.id
WHERE $id IN (w2w.Word1, w2w.Word2):
如果你真的不想这样做,你可以在连接中使用相同的 case 语句:
SELECT w.Word
FROM words_2_words w2w
INNER JOIN words w
ON CASE WHEN w2w.Word1 = $id THEN w2w.Word2 ELSE w2w.Word1 END = w.id
WHERE $id IN (w2w.Word1, w2w.Word2):
【讨论】:
谢谢,IN 部分似乎对我很有效。就性能而言,您的两个建议中哪一个会更好? 我猜是第一个,但在不知道您拥有哪些索引以及您的数据传播范围的情况下,我无法确定。两者都试一下,看看哪个对您的数据最快。 现在我有另一个问题:如何加入单词表,所以我得到了实际的单词。这不起作用:SELECT CASE WHEN word1 = $id THEN word2 ELSE word1 END AS xy FROM words2words LEFT JOIN words ON xy = words.id WHERE $id IN (word1, word2)
【参考方案2】:
如果我理解你所说的正确,你会运行:
select * from words_2_words where word1 = 1 or word2 = 1
尽管您使用联合来组合 2 个查询,但这似乎并不是您真正需要做的。
【讨论】:
感谢您的回答。您的解决方案的问题(我已经尝试过):我没有一个特定的字段来显示两个单词的关系;是word1还是word2?? (抱歉,很难解释。不知道所有的技术术语)以上是关于SQL n:n - 联结表中查询的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章