Oracle SQL:最多加入一个关联实体
我有表 Building
和 Address
,其中每个 Building
与 0..n Addresses
关联。
我想列出带有关联地址
的建筑物
。如果一栋建筑物有多个入口,因此有多个地址,我不在乎显示哪一个。如果建筑物
没有已知地址,则地址字段应为null
。
也就是说,我想要类似左连接的东西,最多连接每行一次。
我如何在 Oracle SQL 中表达这一点?
PS:我的查询将包括对两个表的相当复杂的限制。因此,我想避免在查询文本中重复这些限制。
I have tables Building
and Address
, where each Building
is associated with 0..n Addresses
.
I'd like to list Buildings
with an associated Address
. If a Building
has several entrances, and thus several Addresses
, I don't care which one is displayed. If a Building
has no known addresses, the address fields should be null
.
This is, I want something like a left join that joins each row at most once.
How can I express this in Oracle SQL?
PS: My query will include rather involved restrictions on both tables. Therefore, I'd like to avoid repeating those restrictions in the query text.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我会考虑查询 SELECT 子句中的地址,例如:
ROWNUM=1 意味着“如果有的话就获取一个,不在乎是哪一个”。
这种方法的优点是,只要在addresses.buildingid上存在合适的索引,它的性能可能会比大多数替代方法更好。一旦为所查询的每栋建筑物找到一个地址,它就会停止寻找更多地址。
这种方法的缺点是,如果您想要地址表中的多个列,则不能 - 尽管您可以将它们连接在一起形成一个字符串。
I would consider querying the address in the SELECT clause, e.g.:
The
ROWNUM=1
means "just get one if there are any, don't care which".The advantage of this approach is that it will probably perform better than most alternatives, as long as a suitable index on addresses.buildingid exists. It will stop looking for more addresses as soon as it finds one for each building queried.
The downside to this approach is if you want multiple columns from the address table, you can't - although you can concatenate them together into one string.
因为您不关心显示多个地址中的哪一个:
Oracle 9i+:
非子查询因子分解等效项:
Because you don't care which of many addresses is displayed:
Oracle 9i+:
Non-Subquery Factoring Equivalent:
您可以做的是限制您加入的地址。
例如,要求不存在具有较低 ID 的地址:
在这种情况下,每个建筑物最多可获得 1 个地址。
what you could do is an restriction on the addresses dat you join.
For instance by requiring that there is no address with a lower id:
in this case you will get at most 1 address per building.
或者
or
Meriton,
这种方法使用嵌套内联视图。我已经在大数据集上证明了这种方法,它的表现非常好。
理解查询的最好方法是从最里面的“M”内联视图开始。为了调试和清晰起见,我添加了计数。这标识了每个建筑物的最大(即最近???)地址ID:
下一个“A”内联视图使用上面的“M”内联视图来决定要获取哪个地址,然后连接到该地址ID以返回地址字段集:
上面的“A”内联视图将一组转换后的地址传递给最终查询。 BUILDING 和 ADDRESS 之间的关系是 1 到 0..n,而 BUILDING 和“A”之间的关系是 1 到 0..1,这是一种基本的外连接:
这种方法的主要优点是:
享受吧!
马修
Meriton,
This approach uses nested inline views. I've proven this approach on large data sets, it performs very well.
The best way to understand the query is to start from the inner-most "M" inline view. I added the count for the sake of debugging and clarity. This identifies the maximum (ie. most recent???) address id for each building:
The next "A" inline view uses the above "M" inline view to decide which address to get, then joins to that address id to return a set of address fields:
The above "A" inline view delivers a transformed set of addresses to the final query. Whereas the relationship between BUILDING and ADDRESS is 1 to 0..n, the relationship between BUILDING and "A" is 1 to 0..1, a basic outer-join:
The key advantages with this approach are:
Enjoy!
Matthew