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

Posted

技术标签:

【中文标题】从选择列表中的引用表中选择第 N 行的一列【英文标题】:Selecting one column of the Nth row from a refernced table in the select list 【发布时间】:2019-02-14 13:09:42 【问题描述】:

我有两个表:cross_section 和 layer。

每个横截面都有多个层,依次有一个位置和一个汇总列。位置(整数)用于对每个横截面的层进行排序,但不必连续(例如 10、20、40)。

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

大部分 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】:

问题是这个子句: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 条件来调整窗口子句。如:

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

【讨论】:

谢谢,帮了大忙。正如你所怀疑的,我需要调整 window 子句。

以上是关于从选择列表中的引用表中选择第 N 行的一列的主要内容,如果未能解决你的问题,请参考以下文章

更好的方法来选择第一个表中的所有列,并且只选择第二个表中的一列。

基于sql中另一列的一列中的最大数据

从一列中选择值的所有组合

从表中选择行,其中具有相同 id 的另一个表中的行在另一列中具有特定值

如何为不在第 2 列中的第 1 列选择 SQL

HIVE:如何仅从两个表中的两列中选择第三个表中不存在的不同值?