SQL查询:连接第一个表的实体没有的两个表,或者其他表中的多个条目

时间:2011-06-10 11:36:26

标签: mysql sql database join

我必须使用数据库表,其中第一个表的实体在第二个表中可能有也可能没有关联的条目:

Table 1          Table 2       
+-----+-----+    +-----+-------+-------+
| ID  | ... |    | ID  | T1_ID | NAME  |
+-----+-----+    +-----+-------+-------+
|  1  | ... |    |  1  |   1   |  p1   |
|  2  | ... |    |  2  |   1   |  p2   |
|  3  | ... |    |  3  |   2   |  p1   |
|  4  | ... |    +-----+-------+-------+
+-----+-----+

我需要运行以下查询:

  1. 使用Table_2的特定条目获取Table_1的所有实体 - 这很简单,只需简单的Join即可...

  2. 获取Table_1的所有实体,这些实体没有关联Table_2的特定条目 - 不是那么容易,但我还设法通过连接查询。

  3. 获取Table_1的所有实体,这些实体具有特定条目(A)并且没有关联的其他特定条目(B),即获取Table_1的所有实体,其具有Table_2的实体,名称= p1并且没有Table_2的实体,其名称= p2。

  4. 是否可以在没有子查询的单个sql语句中完成(3)中的查询类型?

4 个答案:

答案 0 :(得分:4)

  

获取Table_1的所有实体,其中   有一个特定的条目(A),没有   有另一个具体条目(B)   关联,即获取所有实体   Table_1具有Table_2的实体   名称= p1且没有实体   Table_2的名称= p2关联。

我在理解你的标准方面遇到了一些麻烦,但我认为这就是你想要的:

SELECT * 
FROM Table1 t1 
JOIN Table2 t2 ON t1.ID = t2.t1_id 
WHERE t2.name = 'p1' 
AND NOT EXISTS(SELECT 'x' FROM Table2 t2_2 WHERE t1.ID = t2_2.t1_id AND t2_2.name = 'p2')

这将为您提供Table1中具有匹配记录的所有内容,其中name ='p1',并且在Table2中没有匹配的记录,名称='p2'。这就是你需要的吗?

再次编辑:

我想到了一种更聪明的方法,它涉及静态(非相关)子查询。此子查询只执行一次,而不是对Table1中的每个父行执行一次。我没有将此代码放在查询分析器中,但它应该比使用EXISTS(...)

的查询快得多
SELECT * 
FROM Table1 t1 
JOIN Table2 t2 ON t1.ID = t2.t1_id 
WHERE t2.name = 'p1' 
AND t1.id NOT IN(SELECT t1_id FROM Table2 WHERE name = 'p2')

答案 1 :(得分:3)

您可以使用EXISTS子查询(实际上与执行两个联接相同)。

SELECT * FROM Table_1 AS t1
WHERE EXISTS (SELECT * FROM Table_2 AS t2 WHERE t1.Id = t2.Id AND Name='p1')
AND NOT EXISTS (SELECT * FROM Table_2 AS t2 WHERE t1.Id = t2.Id AND Name='p2')

答案 2 :(得分:0)

要获得t2与t1.id匹配的所有事件,而不是其他字段

SELECT t1.id, t2.id FROM table2 t2
INNER JOIN table1 t1 ON (t2.t1_id = t1.id AND not(t2.fieldx <=> t1.fieldx))

请注意,这也会排除fieldxnull的行 如果您不希望将<=>替换为=

答案 3 :(得分:0)

使解决方案的变化更加完整:

SELECT t1.*
FROM Table_1 t1
  INNER JOIN Table_2 it2 ON t1.ID = it2.T1_ID AND it2.NAME = 'p1'
  LEFT JOIN Table_2 lt2  ON t1.ID = lt2.T1_ID AND lt2.NAME = 'p2'
WHERE lt2.ID IS NULL