【问题标题】:Oracle - return only the first row for each productOracle - 只返回每个产品的第一行
【发布时间】:2020-01-09 00:46:14
【问题描述】:

在第一个 SELECT 语句中,报告获取所有具有发货活动的产品的 inv 详细信息。然后有一个 UNION 连接另一个 SELECT 语句以获取上一个日历年没有活动的产品。

但是,在第二个 SELECT 语句中返回的记录有多个 header_id,因此是多行……而不是像第一个 SELECT 语句那样单行。你知道如何在第二个 SELECT 语句中只提取每条记录的第一个 header_id 吗?

代码和示例结果集如下。在数据中,产品 #7 应仅列出 header_id 1372288 的行,这是输入数据库的最后一个 ID。

select 3 sort_key, header_Id,location_id,nlasinv.product,
                                   start_inv,produced produced_inv,stored,from_stock,shipped,
                                   (start_inv + produced + stored) - (from_stock + shipped) end_inv,nlas_ops_mtd_prodsize(111,nlasinv.product,'31-DEC-19'), nlas_ops_mtd_shipsize(111,nlasinv.product,'31-DEC-19'),nlas_ops_ytd_prodsize(111,nlasinv.product,'31-DEC-19'), nlas_ops_ytd_shipsize(111,nlasinv.product,'31-DEC-19')
                                   from nlas_header inv,
                                     nlas_inventory nlasinv
                                   where nlasinv.header_id = 1372168   
                                   and inv.id = nlasinv.header_id
    union 
    select distinct
       3 sort_key,header_Id,location_id,nlasinv.product,
       start_inv,produced produced_inv,stored,from_stock,shipped,
                                   (start_inv + produced + stored) - (from_stock + shipped) end_inv,nlas_ops_mtd_prodsize(111,nlasinv.product,'31-DEC-19'),
       nlas_ops_mtd_shipsize(111,nlasinv.product,'31-DEC-19'),nlas_ops_ytd_prodsize(111,nlasinv.product,'31-DEC-19'),
       nlas_ops_ytd_shipsize(111,nlasinv.product,'31-DEC-19')
       from
         nlas_inventory nlasinv,
         nlas_header hdr
         where
         nlasinv.header_id = hdr.id
         and hdr.location_id = 409
         and hdr.observation_date >= trunc(to_date('31-DEC-19','dd-mon-rr'),'year') 
         and nlasinv.product not in
         (select distinct product from
           nlas_header h,
           nlas_inventory i
           where i.header_id = 1372168) 
order by product, header_id des

c

【问题讨论】:

  • 如何定义“第一行”?最小日期、值、其他?
  • “第一行”将是具有最高 header_id 的行...相当于最近的记录。
  • 那么戈登的回答是正确的。在他的回答中,t 代表您拥有的整个查询(除了应该放在解决方案之后(最后)的最后一个 ORDER BY 子句。

标签: sql oracle


【解决方案1】:

我不知道您的查询与您显示的“表格”数据有什么关系。但你似乎想要row_number()

select t.*
from (select t.*, row_number() over (partition by product order by header_id desc) as seqnum
      from t
     ) t
where seqnum = 1;

如果该查询用于生成数据,则只需将其包装在 CTE 中。

【讨论】:

  • 感谢您的反馈。我想确定我理解...我是否使用 Gordon 列出的方法来包装我的整个声明?为了简化我的查询: select header_Id,product,start_inv,produced,stored,from_stock,shipped from nlas_header inv, nlas_inventory nlasinv where inv.id = nlasinv.header_id union select header_Id,product,start_inv,produced,stored,from_stock,shipped from nlas_inventory nlasinv, nlas_header hdr where nlasinv.header_id = hdr.id and hdr.observation_date >= '01-DEC-19' order by product, header_id desc
  • @user2470781 。 . . with t as (<your query here>) <the above query>.
  • 你成功了,戈登!我能够返回我期望的行。感谢您的帮助,也感谢 Impaler 的帮助。
【解决方案2】:

这也可以通过在 where 子句中添加自联接来实现

and hdr.header_id = (
   select max(hdr2.header_id) 
   from nlas_header hdr2 
   where hdr2.location_id = hdr.location_id 
   and hdr2.product_id = hdr.product_id)

【讨论】:

    猜你喜欢
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多