Question

I have a synonym database which has two tables, "synonyms" and "synonyms_relations" like so...

synonyms
-------
id
word

synonyms_relations
------------------
id
word1_id
word2_id

I want to be able to get all words that are related to each other. The synonyms_relations table DOES NOT have records for matches in both directions, meaning if word1 is linked to word2, there wont be a record linking word2 to word1 - its assumed to work both directions.

This is the query I have to find all synonyms of the word "car". It works, but it seems way too complicated for my needs. Is there a better more efficient way to write this?

SELECT
  s.`word`
FROM
  `synonyms` as s
WHERE s.`id` IN (
  SELECT `word1_id` FROM `synonyms_relations` WHERE `word2_id` = (SELECT `id` FROM `synonyms` WHERE `word` = 'car')
    UNION
  SELECT `word2_id` FROM `synonyms_relations` WHERE `word1_id` = (SELECT `id` FROM `synonyms` WHERE `word` = 'car')
)
Was it helpful?

Solution

The following would seem to offer what you are looking for:

SELECT  s.`word`
  FROM  `synonyms` s
    LEFT JOIN `synonyms_relations` sr1 ON sr1.word1_id = s.id
    LEFT JOIN `synonyms` s1 ON s1.id = sr1.word2_id
    LEFT JOIN `synonyms_relations` sr2 ON sr2.word2_id = s.id
    LEFT JOIN `synonyms` s2 ON s2.id = sr2.word1_id
  WHERE (s1.`word` = 'car' OR s2.`word` = 'car')

Effectively, joining all words that have a matching word2_id (via sr1 and s1) and all words that have a matching word1_id (via sr2 and s2).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top