[英]SQL Query: Joining two tables where entity of the first table has no, or multiple entries in other table
I have to database tables, where entities of the first Table may or may not have associated entries in the second table:我必须数据库表,其中第一个表的实体可能有也可能没有第二个表中的关联条目:
Table 1 Table 2
+-----+-----+ +-----+-------+-------+
| ID | ... | | ID | T1_ID | NAME |
+-----+-----+ +-----+-------+-------+
| 1 | ... | | 1 | 1 | p1 |
| 2 | ... | | 2 | 1 | p2 |
| 3 | ... | | 3 | 2 | p1 |
| 4 | ... | +-----+-------+-------+
+-----+-----+
I have the following queries i need to run:我有以下需要运行的查询:
Get all entities of Table_1 with a specific entry of Table_2 - That's easy, a simple Join will do...使用 Table_2 的特定条目获取 Table_1 的所有实体 - 这很容易,一个简单的 Join 就可以了......
Get all entities of Table_1, which don't have a specific entry of Table_2 associated - not so easy, but i also managed to query this with a join.获取 Table_1 的所有实体,它们没有关联 Table_2 的特定条目 - 不是那么容易,但我也设法通过连接查询它。
Get all entities of Table_1, which have a specific entry (A) and don't have another specific entry (B) associated, ie get all entities of Table_1 that have an entity of Table_2 with name=p1 and don't have an entity of Table_2 with name=p2 associated.获取 Table_1 的所有实体,它们具有特定条目 (A) 并且没有关联另一个特定条目 (B),即获取 Table_1 的所有实体,这些实体具有 Table_2 的 name=p1 的实体并且没有实体与 name=p2 关联的 Table_2。
Is it possible to accomplish the kind of query from (3) in a single sql-statement without a sub-query?是否可以在没有子查询的情况下在单个 sql 语句中完成 (3) 中的那种查询?
Get all entities of Table_1, which have a specific entry (A) and don't have another specific entry (B) associated, ie get all entities of Table_1 that have an entity of Table_2 with name=p1 and don't have an entity of Table_2 with name=p2 associated.
获取 Table_1 的所有实体,它们具有特定条目 (A) 并且没有关联另一个特定条目 (B),即获取 Table_1 的所有实体,这些实体具有 Table_2 的 name=p1 的实体并且没有实体与 name=p2 关联的 Table_2。
I'm having a bit of trouble understanding your criteria, but I think that is what you want:我在理解您的标准时遇到了一些麻烦,但我认为这就是您想要的:
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')
That will give you everything from Table1 that has a matching record in Table2 with name = 'p1' and DOESN'T have a matching record in Table2 with name = 'p2'.这将为您提供 Table1 中的所有内容,这些记录在 Table2 中具有名称 = 'p1' 的匹配记录,并且在 Table2 中没有名称 = 'p2' 的匹配记录。 Is that what you need?
那是你需要的吗?
EDIT AGAIN:再次编辑:
I thought of a smarter way to do this that involves a static (non-correlated) subquery.我想到了一种更聪明的方法来做到这一点,它涉及 static(非相关)子查询。 This subquery will only be executed one time, rather than being executed once for every parent row in Table1.
该子查询只会执行一次,而不是对 Table1 中的每个父行执行一次。 I didn't put this code through a query analyzer, but it should be significantly faster than of the queries using EXISTS(...)
我没有通过查询分析器输入这段代码,但它应该比使用 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')
You can use an EXISTS
subquery (effectively the same as doing two joins).您可以使用
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')
To get all occurrences where t2 matches t1.id but not some other field do要获取 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))
Note that this will also exclude rows where both fieldx
are null
.请注意,这还将排除两个
fieldx
均为null
的行。
If you don't want that substitute the <=>
with =
.如果您不希望将
<=>
替换为=
。
To make the variation of solutions more complete:为了使解决方案的变化更完整:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.