SQL n:n - лучшая практика для запросов в соединительной таблице

Я знаю, что для SQL n:n уже запущено много вопросов. Однако я не мог найти решение для моей проблемы.

Я хотел бы создать проект, похожий на личный тезаурус. В нем пользователь может определить, какое слово относится к другим словам. У меня есть две таблицы:

words:
+----+-----------+
| id | word      |
+----+-----------+
|  1 | house     |
|  2 | residence |
+----+-----------+

words_2_words (junction table)
+----+-------+-------+
| id | word1 | word2 |
+----+-------+-------+
|  1 |     1 |     2 |
+----+-------+-------+

Найти все синонимы для дома довольно легко:

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 запроса в один запрос для более быстрого результата?

2 ответа

Решение

Вы могли бы использовать 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):

Если я правильно понимаю, что вы говорите, вы просто запустите:

select * from words_2_words where word1 = 1 or word2 = 1

Хотя вы объединяете 2 запроса, используя объединение, это не похоже на то, что вам действительно нужно делать.

Другие вопросы по тегам