选择尚未针对特定列值创建的记录

时间:2012-08-24 14:36:34

标签: mysql sql many-to-many

有两个表:

content_term
    cid | tid
    1 | 1
    1 | 2
    1 | 3
    2 | 4
    2 | 5
    2 | 6

term_group
    tid | gid
    1 | 1
    2 | 2
    3 | 3
    4 | 1
    5 | 2
    6 | 3

如何通过“tid”选择“cid”与某些“gid”无关?

UPD 我已经尝试过Adrian通过cid进行分组的方式:

SELECT cid 
FROM   content_term ct 
WHERE  NOT EXISTS (SELECT tid 
               FROM   term_group tg 
               WHERE  tg.tid = ct.tid 
                      AND tg.gid = 4) GROUP BY cid;

还尝试了Adrian通过cid进行分组的方式:

SELECT cid FROM content_term
    LEFT JOIN term_group ON (content_term.tid = term_group.tid AND gid = 4)
    WHERE gid IS NULL GROUP BY cid;

在“gid”= 3或任何其他值上 - 两者都返回:

cid
1
2

2 个答案:

答案 0 :(得分:0)

SELECT cid 
FROM   content_term ct 
WHERE  NOT EXISTS (SELECT tid 
                   FROM   term_group tg 
                   WHERE  tg.tid = ct.tid 
                          AND tg.gid = 4) 

答案 1 :(得分:0)

此:

SELECT DISTINCT cid FROM content_term
    JOIN term_group ON (content_term.tid = term_group.tid AND gid = 4);

将使用gid 4映射所有cid。我们现在要求content_term中的所有cid在此列表中。因此,我们在唯一的cid和我们刚检索到的附加cid之间使用LEFT JOIN

SELECT unique_cids.cid FROM ( SELECT DISTINCT cid FROM content_term ) AS unique_cids
    LEFT JOIN ( SELECT DISTINCT cid FROM content_term
       JOIN term_group ON (content_term.tid = term_group.tid AND gid = 4) )
           AS attached_cids ON (unique_cids.cid = attached_cids.cid)
    WHERE attached_cids.cid IS NULL;

测试:

CREATE TABLE content_term ( cid integer, tid integer );
CREATE TABLE term_group ( tid integer, gid integer );
INSERT INTO content_term VALUES (1,1),(1,2),(1,3),(2,4),(2,5),(2,6);
INSERT INTO term_group VALUES (1,1),(2,2),(3,3),(4,1),(5,2),(6,3);

首先尝试使用gid 4:

SELECT unique_cids.cid FROM ( SELECT DISTINCT cid FROM content_term )
   AS unique_cids
LEFT JOIN ( SELECT DISTINCT cid FROM content_term        
JOIN term_group ON (content_term.tid = term_group.tid AND gid = 4)) 
          AS attached_cids ON (unique_cids.cid = attached_cids.cid)
     WHERE attached_cids.cid IS NULL;

+------+
| cid  |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)

使用gid 3重试:

SELECT unique_cids.cid FROM ( SELECT DISTINCT cid FROM content_term ) 
    AS unique_cids
     LEFT JOIN ( SELECT DISTINCT cid FROM content_term
        JOIN term_group ON (content_term.tid = term_group.tid AND gid = 3))
            AS attached_cids ON (unique_cids.cid = attached_cids.cid)
     WHERE attached_cids.cid IS NULL;

Empty set (0.00 sec)