我必须使用数据库表,其中第一个表的实体在第二个表中可能有也可能没有关联的条目:
Table 1 Table 2
+-----+-----+ +-----+-------+-------+
| ID | ... | | ID | T1_ID | NAME |
+-----+-----+ +-----+-------+-------+
| 1 | ... | | 1 | 1 | p1 |
| 2 | ... | | 2 | 1 | p2 |
| 3 | ... | | 3 | 2 | p1 |
| 4 | ... | +-----+-------+-------+
+-----+-----+
我需要运行以下查询:
使用Table_2的特定条目获取Table_1的所有实体 - 这很简单,只需简单的Join即可...
获取Table_1的所有实体,这些实体没有关联Table_2的特定条目 - 不是那么容易,但我还设法通过连接查询。
获取Table_1的所有实体,这些实体具有特定条目(A)并且没有关联的其他特定条目(B),即获取Table_1的所有实体,其具有Table_2的实体,名称= p1并且没有Table_2的实体,其名称= p2。
是否可以在没有子查询的单个sql语句中完成(3)中的查询类型?
答案 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))
请注意,这也会排除fieldx
为null
的行
如果您不希望将<=>
替换为=
。
答案 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