Oracle 将多行合并为一行
我正在使用一个在 Oracle 中创建并通过 SDE 在 GIS 软件中使用的数据库。我的一位同事要从此数据库中进行一些统计,但我无法找到合理的 SQL 查询来获取数据。
我有两张桌子,一张有注册信息,一张有注册详细信息。这是一种一对多的关系,因此注册可以有一个或多个与之相关的详细信息(没有最大数量)。
- table: Registration
RegistrationID Date TotLenght 1 01.01.2010 5 2 01.02.2010 15 3 05.02.2009 10
2.table: RegistrationDetail
DetailID RegistrationID Owner Type Distance 1 1 TD UB 1,5 2 1 AB US 2 3 1 TD UQ 4 4 2 AB UQ 13 5 2 AB UR 13,1 6 3 TD US 5
我希望结果选择是这样的:
RegistrationID Date TotLenght DetailID RegistrationID Owner Type Distance DetailID RegistrationID Owner Type Distance DetailID RegistrationID Owner Type Distance 1 01.01.2010 5 1 1 TD UB 1,5 2 1 AB US 2 3 1 TD UQ 4 2 01.02.2010 15 4 2 AB UQ 13 5 2 AB UR 13,1 3 05.02.2009 10 6 3 TD US 5
使用正常的连接,每个注册和详细信息都会得到一行。谁能帮我解决这个问题吗?我没有数据库的管理员权限,因此无法创建任何表或变量。如果可能的话,我可以将表复制到 Access 中。
I'm working with a database which is created in Oracle and used in a GIS-software through SDE. One of my colleuges is going to make some statistics out of this database and I'm not capable of finding a reasonable SQL-query for getting the data.
I have two tables, one with registrations and one with registrationdetails. It's a one to many relationship, so the registration can have one or more details connected to it (no maximum number).
- table: Registration
RegistrationID Date TotLenght 1 01.01.2010 5 2 01.02.2010 15 3 05.02.2009 10
2.table: RegistrationDetail
DetailID RegistrationID Owner Type Distance 1 1 TD UB 1,5 2 1 AB US 2 3 1 TD UQ 4 4 2 AB UQ 13 5 2 AB UR 13,1 6 3 TD US 5
I want the resulting selection to be something like this:
RegistrationID Date TotLenght DetailID RegistrationID Owner Type Distance DetailID RegistrationID Owner Type Distance DetailID RegistrationID Owner Type Distance 1 01.01.2010 5 1 1 TD UB 1,5 2 1 AB US 2 3 1 TD UQ 4 2 01.02.2010 15 4 2 AB UQ 13 5 2 AB UR 13,1 3 05.02.2009 10 6 3 TD US 5
With a normal join I get one row per each registration and detail. Can anyone help me with this? I don't have administrator-rights for the database, so I can't create any tables or variables. If it's possible, I could copy the tables into Access.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果详细记录的最大数量是固定的并且已知,则可以完成此操作。数字越大,查询编码就越繁琐。这就是大自然给我们剪切和粘贴的原因。
以下查询使用了一些技巧。公共表表达式(又名子查询分解)子句封装了 RegistrationDetail 上的查询,因此我们可以轻松地在多个位置引用它。子查询使用分析函数 ROW_NUMBER(),它允许我们识别 RegistrationID 组中的每个详细记录。这两个功能都是在 Oracle 9i 中引入的,因此它们并不是新功能,但很多人仍然不了解它们。
主查询使用外连接将注册表多次连接到子查询中的行。它连接 RegistrationID 和派生的 DetNo。
显然,如果每个 RegistrationID 有四个详细记录,您将需要其中四个外部联接(以及投影中的四组列)。
编辑
我刚刚重新阅读了您的问题,发现了可怕的词语“没有最大数量”。抱歉,那样的话你就不走运了。使用可变数量的集合解决此问题的唯一方法是使用动态 SQL,您已有效地排除了这种方法(因为您需要创建额外的架构对象)。
编辑2
还有另一种解决方案,它只是提取数据并忘记布局。 Oracle 允许我们在投影中与标量一起声明内联游标,即嵌套的
select
语句。这解决了向客户端工具显示输出的问题。在此版本中,我使用 Oracle 的内置 XML 功能来生成输出(基于目前许多工具都可以呈现 XML)。 RegistrationDetails 记录分组在名为 REG_DETAILS 的 XMLElement 中,该元素嵌套在每个注册记录中。
If the maximum number of Detail records is fixed and known then this can be done. The larger the number the more tedious the query is to code. That's why Nature gave us cut'n'paste.
The following query uses a couple of tricks. The Common Table Expression (aka Sub-Query Factoring) clause encapsulates the query on RegistrationDetail so we can easily refer to it in multiple places. The sub-query uses an Analytic function ROW_NUMBER() which allows us to identify each Detail record within the RegistrationID group. Both these features wwre introduced in Oracle 9i so they aren't new, but lots of people still don't know about them.
The main query uses Outer Joins to connect the Registration table multiple times to rows in the sub-query. It joins on RegistrationID and the derived DetNo.
Obviously if you have four Detail records per RegistrationID you will need four of those Outer Joins (and four sets of columns in the projection).
edit
I have just re-read your question and spotted the dread words "No maximum number". Sorry, in that case you're out of luck. The only way of solving this problem with a variable number of sets is with dynamic SQL, which you have effectively ruled out (because you would need to create additional schema objects).
edit 2
There is another solution, which is just about extracting the data and forgetting the layout. Oracle allows us to declare inline cursors, that is nested
select
statements, in the projection alongside scalars. This passes the problem of displaying the output to a client tool.In this version I use Oracle's built-in XML functionality to produce the output (on the basis that lots of tools can render XML these days). The RegistrationDetails records are group within an XMLElement called REG_DETAILS which is nested within each Registration record.
在同一个查询中不能有多个具有相同名称的列 - Oracle 会将它们重命名为“Date_1”、“Date_2”等。拥有多行有什么问题?您如何访问它?
You can't have multiple columns with the same name in the same query - oracle will rename them as 'Date_1', 'Date_2' etc. What is wrong with having several rows? How are you accessing it?