从选择列表中的引用表中选择第N行的一列

时间:2019-02-14 13:09:43

标签: sql oracle subquery

我有两个表:cross_section和layer。

每个横截面都有多个层,这些层又有一个位置和一个摘要列。位置(整数)用于对每个横截面的层进行排序,但不必是连续的(例如10、20、40)。

我需要将查询扩展到cross_section表,以包括每个横截面图层的摘要(固定数> 1),这些摘要保留了position属性定义的顺序。

大多数SQL是自动生成的;我只能将包含子查询的其他元素添加到选择列表中。 这是自动生成的SQL的样子:

select cs.*, [first layer summary], [second layer summary]... from cross_section cs;

我尝试了多种不同的方法,但是没有一个能按预期工作(也许根本不可能)。

我当前的非工作状态如下:

---------------generated------------------------------------------
select cs.*,
---------------partial statment for clumn one---------------------
    (select summary 
    from (select summary, l.cs_id 
         from layer l order by layer_position)
    where cross_section.id like cs_id and rownum=1) layer_summary_1,
---------------partial statment for clumn two---------------------
    (select summary 
    from (select summary, l.cs_id 
         from layer l order by layer_position)
    where cross_section.id like cs_id and rownum=2) layer_summary_2
---------------generated------------------------------------------
from cross_section cs;

现在,除了第一个位置之外,其他所有内容都返回null。

编辑: 根据要求输出示例:

CSID,   Stuff from cross section,   layer_summary_1,    layer_summary_2
12345,  ...,                        stuff               (null)

1 个答案:

答案 0 :(得分:0)

问题是该子句:rownum=2

rownum伪列枚举所生成结果集中的行。因此,有一个rownum = 1返回一行;这就是为什么您发现第一个位置恢复了预期的原因。但是永远不会有rownum = 2。 (rownum <= 2返回两行,因为其中rownum = 1所在的行。)

解决方案很简单:在子查询中使用解析row_number()函数,您可以在主WHERE子句中引用该函数:

---------------generated------------------------------------------
select cs.*,
---------------partial statment for clumn one---------------------
    (select summary 
    from (select summary, l.cs_id  
                 , row_number() over (order by layer_position) as rn 
         from layer l order by layer_position)
    where cross_section.id like cs_id and rn=2)
---------------partial statment for clumn two---------------------
    (select summary 
    from (select summary, l.cs_id 
                 , row_number() over (order by layer_position) as rn 
         from layer l order by layer_position)
    where cross_section.id like cs_id and rn=2)
---------------generated------------------------------------------
from cross_section cs;

您不清楚数据或业务逻辑的问题,因此以上内容可能会产生错误的结果。如果是这样,您需要通过添加PARTITION BY条件来调整window子句。如:

  , row_number() over (partition by cs_id order by layer_position) as rn