左外连接与同一个表作为外连接的一部分
我想知道如何通过编写外连接查询来获取所需的输出(如下所述) 我外部连接的表是语句中其他连接条件的一部分,
给出以下数据结构,其中 - 表A是包含一些任意对象的主表 - 表 B 由 A 引用,其中 A.TYPE_ID = B.ID - 表 C 定义表 A 中的对象之间的关系,其中 C.SOURCE_ID 引用 A.ID 和 C.TARGET_ID 引用 A.ID
这就是模式的定义方式,我对此无能为力(这是一个遗留系统
TABLE_A
---------------------------
| ID | TYPE_ID | Name |
|-------------------------|
| 1 | 1 | Name 1 |
| 2 | 2 | Name 2 |
| 3 | 1 | Name 3 |
| 4 | 1 | Name 4 |
| 5 | 3 | Name 5 |
|-------------------------|
TABLE_B
----------------------
| ID | TYPE_NAME |
|--------------------|
| 1 | Type 1 |
| 2 | Type 2 |
| 3 | Type 3 |
| 4 | Type 4 |
|--------------------|
TABLE_C
-------------------------------
| PK | SOURCE_ID | TARGET_ID |
|-----------------------------|
| 11 | 2 | 1 |
| 12 | 2 | 3 |
| 13 | 5 | 1 |
| 13 | 5 | 4 |
-------------------------------
)我想获取“类型 1”表 A 中的所有对象及其关联的对象名称(否则为 null),属于类型 2, 即一个外部联接来获取类型 1 的所有对象,无论它们是否具有关联,但如果它们具有关联,那么我需要该对象的名称。 请注意,类型 1 的对象将始终位于关系的 TARGET 中。
上面示例的输出将是
-------------------------------
| Target Name | Source Name |
|-----------------------------|
| Name 1 | Name 2 |
| Name 3 | Name 2 |
| Name 4 | (NULL) |
|-----------------------------|
我的原始连接查询(无法使外部连接工作),这是正常的连接,不显示没有关联的对象。
select atrgt.NAME, asrc.NAME
from TABLE_A atrgt
JOIN TABLE_B trgttype on atrgt.TYPE_ID = trgttype.ID
and trgttype.TYPE_NAME = 'Type 1'
JOIN TABLE_C assoc on atrgt.ID = assoc.TARGET_ID
JOIN TABLE_A asrc on asrc.ID = assoc.SOURCE_ID
JOIN TABLE_B srctype on asrc.TYPE_ID = srctype.ID
and srctype.TYPE_NAME = 'Type 2'
I was wondering how I could go by writing a the outer join query to get the required outputs (described below)
where the tables I am outer joining are part of the other join conditions in the statement
given the following datastructure where
- Table A is the main table containing some arbitrary objects
- Table B is referenced by A where A.TYPE_ID = B.ID
- Table C defininfs relations between the objects in Table A where C.SOURCE_ID references A.ID and C.TARGET_ID references A.ID
This is how the schema is defined and I can't do anything about it (it's a legacy system)
TABLE_A
---------------------------
| ID | TYPE_ID | Name |
|-------------------------|
| 1 | 1 | Name 1 |
| 2 | 2 | Name 2 |
| 3 | 1 | Name 3 |
| 4 | 1 | Name 4 |
| 5 | 3 | Name 5 |
|-------------------------|
TABLE_B
----------------------
| ID | TYPE_NAME |
|--------------------|
| 1 | Type 1 |
| 2 | Type 2 |
| 3 | Type 3 |
| 4 | Type 4 |
|--------------------|
TABLE_C
-------------------------------
| PK | SOURCE_ID | TARGET_ID |
|-----------------------------|
| 11 | 2 | 1 |
| 12 | 2 | 3 |
| 13 | 5 | 1 |
| 13 | 5 | 4 |
-------------------------------
What I would like to get is all the objects in Table A of "Type 1" with the name of the object they are associated to (null otherwise) which are of Type 2,
i.e an outer join to get all the objects of Type 1 regardless if they have an association, but if they do then I need the name of the object.
Note that objects of Type 1 will always been in the TARGET in the relstionship.
The output for the above example would be
-------------------------------
| Target Name | Source Name |
|-----------------------------|
| Name 1 | Name 2 |
| Name 3 | Name 2 |
| Name 4 | (NULL) |
|-----------------------------|
My original join query (couldn't get the outer join to work) this is the normal join not showing objects with no associations.
select atrgt.NAME, asrc.NAME
from TABLE_A atrgt
JOIN TABLE_B trgttype on atrgt.TYPE_ID = trgttype.ID
and trgttype.TYPE_NAME = 'Type 1'
JOIN TABLE_C assoc on atrgt.ID = assoc.TARGET_ID
JOIN TABLE_A asrc on asrc.ID = assoc.SOURCE_ID
JOIN TABLE_B srctype on asrc.TYPE_ID = srctype.ID
and srctype.TYPE_NAME = 'Type 2'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
基本上在这些情况下,我认为最好的方法是将查询细分为两个普通联接,然后在这些结果集之间进行外联接。如果您将 SQL 视为过程代码,您可能会认为它看起来效率低下,但查询优化器不一定会独立运行两个子联接。
你没有说你正在使用什么RDBMS。在 Oracle 中我可能会这样写:
Basically in these situations I think the best approach is to subdivide the query into two normal joins, then do the outer join between those results sets. If you think of SQL as procedural code, you may think it looks inefficient, but the query optimizer will not necessarily run the two subjoins independently.
You didn't say what RDBMS you are using. In Oracle I would probably write it like this:
尝试
Try
我认为这应该可行:
如果您使用的是 Oracle,则可以将
COALESCE
替换为NVL(SRC_TYPE.TYPE_NAME, 'Type 2')
。I think this should work:
If you're using Oracle, you could replace the
COALESCE
withNVL(SRC_TYPE.TYPE_NAME, 'Type 2')
.