计算多对多的关联记录

时间:2013-01-24 10:52:24

标签: mysql sql ruby-on-rails

我在wordsdefinitions之间有多对多关联。

words:
+-----------------+--------------+------+-----+---------+----------------+
| Field           | Type         | Null | Key | Default | Extra          |
+-----------------+--------------+------+-----+---------+----------------+
| id              | int(11)      | NO   | PRI | NULL    | auto_increment |
+-----------------+--------------+------+-----+---------+----------------+

definitions:
+-------------------+--------------+------+-----+---------+----------------+
| Field             | Type         | Null | Key | Default | Extra          |
+-------------------+--------------+------+-----+---------+----------------+
| id                | int(11)      | NO   | PRI | NULL    | auto_increment |
| language_id       | int(11)      | YES  | MUL | NULL    |                |
+-------------------+--------------+------+-----+---------+----------------+

definitions_words:
+---------------+---------+------+-----+---------+-------+
| Field         | Type    | Null | Key | Default | Extra |
+---------------+---------+------+-----+---------+-------+
| definition_id | int(11) | NO   | PRI | NULL    |       |
| word_id       | int(11) | NO   | PRI | NULL    |       |
+---------------+---------+------+-----+---------+-------+

我想获得所有单词记录,其中只有一个定义language_id = 1

2 个答案:

答案 0 :(得分:2)

我认为在SQL中表达这一点的最简单方法是使用in

select *
from words
where id in (select word_id
             from word_definitions
             where language_id = 1
             having count(*) = 1
            )

但是,带有子查询的in在MySQL中并不总是有效。它可以用exists子句替换:

select *
from words w
where exists (select 1
              from word_definitions wd
              where language_id = 1
              having count(*) = 1 and wd.word_id = w.id
             )

答案 1 :(得分:1)

SELECT  a.ID, COUNT(*) totalRecordCount
FROM    words a
        INNER JOIN definition_words b
            ON a.ID = b.word_ID
        INNER JOIN definitions c
            ON b.definition_id = c.ID
        INNER JOIN
        (
            SELECT  id,
                    SUM(language = 1) totalCount
            FROM    definitions
            GROUP   BY id
        ) d ON c.ID = d.ID AND 
               d.TotalCount = 1
GROUP   BY a.ID