Oracle 19:根据第三列的最大值查找经过筛选的行子集的 ID

问题描述 投票:0回答:1

给定一个包含 4 列或更多列的“摘要”表:

(ID1, ID2, SortOrder, BooleanYN)

对于

ID1
的每个值,我想要与具有最高
ID2
值的
BooleanYN = Y
行相对应的
SortOrder
值(如果存在此类记录)。

示例:

ID1 ID2 排序 布尔YN
1 10 1
1 20 2 N
1 30 3
1 40 4 N

我正在寻找

(1, 30)
,因为具有
SortOrder
ID1 = 1
的“最新”(基于
BooleanYN = 'Y'
)行是具有
ID2 = 30
的行。

我在这里用示例数据构建了一个 SQL Fiddle:

http://sqlfiddle.com/#!4/a5bc5/6

此查询在 Fiddle 中不起作用,因为 Oracle 11g 不支持

OUTER APPLY
,但它在 Oracle 19 中有效。

SELECT
  p.person_id,
  mmr.appointment_id,
  flu.appointment_id,
  covid.appointment_id,
  hiv.appointment_id
FROM
  person p
  OUTER APPLY (
    SELECT vs.appointment_id
      FROM vaccination_summary vs
     WHERE vs.person_id = p.person_id
       AND mmr_yn = 'Y'
     ORDER BY vs.appointment_date DESC
     FETCH FIRST ROW ONLY
  ) mmr
  OUTER APPLY (
    SELECT vs.appointment_id
      FROM vaccination_summary vs
     WHERE vs.person_id = p.person_id
       AND flu_yn = 'Y'
     ORDER BY vs.appointment_date DESC
     FETCH FIRST ROW ONLY
  ) flu
  OUTER APPLY (
    SELECT vs.appointment_id
      FROM vaccination_summary vs
     WHERE vs.person_id = p.person_id
       AND covid_yn = 'Y'
     ORDER BY vs.appointment_date DESC
     FETCH FIRST ROW ONLY
  ) covid
  OUTER APPLY (
    SELECT vs.appointment_id
      FROM vaccination_summary vs
     WHERE vs.person_id = p.person_id
       AND hiv_yn = 'Y'
     ORDER BY vs.appointment_date DESC
     FETCH FIRST ROW ONLY
  ) hiv;

看起来SUPER不优雅且效率低下。

当然必须有更好的方法来使用窗口函数来做到这一点......或者也许取消旋转然后重新旋转?

sql oracle pivot window-functions
1个回答
0
投票

方法很多。一种是窗口化,它本身可以通过多种方式完成。这是一个:

SELECT *
  FROM (SELECT x.*,
               ROW_NUMBER() OVER (PARTITION BY id1 ORDER BY DECODE(BooleanYN,'Y',1,2),SortOrder DESC) seq
          FROM tablename x)
 WHERE seq = 1

一种没有子查询的旧预窗口方法:

SELECT id1,
       SUBSTR(MAX(DECODE(BooleanYN ='Y',1,2)||TO_CHAR(LPAD(SortOrder,3,'0')||id2),4) id2
  FROM tablename
 GROUP BY id1

当然还有子查询方法:

SELECT id1,
       id2
  FROM tablename t1
 WHERE sortorder = (SELECT MAX(sortorder)
                      FROM tablename t2
                     WHERE t2.id1 = t1.id1
                       AND t2.booleanyn = 'Y')
   AND boooleanyn = 'Y'

             
© www.soinside.com 2019 - 2024. All rights reserved.