2012-06-04 56 views
0

我有一张表格,可以将单词相互联系起来。SQL获取与所有键相关的所有结果

table_word_relationships 
+-------------+-------------+ 
| WORD_A | WORD_B  | 
+-------------+-------------+ 
| cat  | dog  | 
+-------------+-------------+ 
| cat  | rabbit | 
+-------------+-------------+ 
| owl  | cat  | 
+-------------+-------------+ 
| bird  | dog  | 
+-------------+-------------+ 
| dog  | banana | 
+-------------+-------------+ 
| banana | cat  | 
+-------------+-------------+ 

我需要运行两种类型的查询。一个很容易。给我所有涉及到的单词“狗”

"SELECT * FROM table_word_relationships WHERE WORD_A = 'dog' OR WORD_B = 'dog'"; 

的话,结果将是:

cat 
bird 
banana 

第二个是我遇到问题的一个... 我需要查询所有与单词列表中所有单词有关的单词...

因此,在英语中,我会说“给我所有与单词”dog“有关系的单词,还有与单词“CAT”有关系 结果wo可能是:

banana 

因为香蕉是唯一与两个关键词有关的词。什么是适当的SQL语句类型呢?

+1

见有很多这种类似的问题(超过10个)的方式来做到这此:如何筛选SQL结果在一个有很多通过关系](http://stackoverflow.com/questions/7364969/how-to-filter-sql-results-in-a-has-many-through-relation) –

+0

你的第一个结果查询将是两列。而对于第二个,我认为你需要重新设计你的数据模型。你需要一张表格来表达文字和关系。然后你可以轻松地查询它们。除非这是一项家庭作业,否则我会强烈建议更改数据模型。 – Adam

+1

@adam,我确实有单独的表格,这只是一个我认为会更容易理解的例子。 –

回答

2

查询1应该是:因为你存储在只有一行的每个连接

SELECT word_b AS word 
FROM table_word_relationships 
WHERE word_a = 'dog' 

UNION DISTINCT 

SELECT word_a 
FROM table_word_relationships 
WHERE word_b = 'dog' ; 

查询2变得相当复杂。一种可能的方式:

SELECT 
    dog.word 
FROM 
    (SELECT word_b AS word 
    FROM table_word_relationships 
    WHERE word_a = 'dog' 

    UNION DISTINCT 

    SELECT word_a 
    FROM table_word_relationships 
    WHERE word_b = 'dog' 
) AS dog 

    JOIN 

    (SELECT word_b AS word 
    FROM table_word_relationships 
    WHERE word_a = 'cat' 

    UNION DISTINCT 

    SELECT word_a 
    FROM table_word_relationships 
    WHERE word_b = 'cat' 
) AS cat 

    ON cat.word = dog.word ; 

无论你的查询会如果你存储所有的连接两排,既(cat, dog)(dog, cat)简单得多。

查询1,则:

SELECT word_b AS word 
FROM table_word_relationships 
WHERE word_a = 'dog' ; 

查询2:

SELECT 
    dog.word_b AS word 
FROM 
    table_word_relationships AS dog 
    JOIN 
    table_word_relationships AS cat 
     ON cat.word_b = dog.word_b 
WHERE 
     dog.word_a = 'dog' 
    AND 
     cat.word_a = 'cat' ; 
+0

ypercube,我一定要听从你的建议,并为每个插入添加两行。 –

0

您可以使用SQL中的INTERSECT命令查找多个查询的交集;即返回所有人共有的东西。

例如为:

select field1 from table1 where id = 5 
intersect 
select field1 from table2 where id < 5 
+0

有趣。我在每个关键字的查询中运行PHP的相交,我想在SQL中处理它会更快。我会研究这个。 –

+0

MySQL没有实现'INTERSECT'。 –

0

正如您在您的评论解释,你有2个表。我认为第一个表格叫做words,有两列:idword。并且关系表包含单词表的id和id2外键。

那么你可以尝试这样的:

select distinct word from words w 
where 
(exists 
(select * from table_word_relationships r 
inner join word w2 on w2.id = r.id2 
inner join word w3 on w3.id = r.id 
where (w.id = r.id1 and w2.word = "CAT") or (w.id = r.id2 and w3.word = "CAT")) 
and 
(exists 
(select * from table_word_relationships r 
inner join word w2 on w2.id = r.id2 
inner join word w3 on w3.id = r.id 
where (w.id = r.id1 and w2.word = "DOG") or (w.id = r.id2 and w3.word = "DOG")) 

(未测试)