[英]Handle Max function on Null values or returning multiple values
我在下面有2个表格结构,我需要获取对应于特定事件的最大值verify_dt_tm的结果。 如果某个特定事件具有相同的verify_dt_tm,我需要根据该特定事件的最大result_id来获取它。 我在下面写了一个示例查询。 它不适用于非null值,但不适用于NULL。 我已将COALESCE用于NULL值,但由于外部查询仍将包含verify_dt_tm作为它们将不匹配的空广告,因此无法正常工作。 下面是表格的详细说明。
订单表
order_id order_status
12345 Completed
结果表
result_table_id order_id event verified_dt_tm result_value
98765 12345 Basophils count 22/02/19 11:00 12
87654 12345 monocytes count 21/02/19 15:00 34
76543 12345 lymphocytes count 21/02/19 14:44 35
76542 12345 rbcytes count 35
76540 12345 rbcytes count 1
76532 12345 rbcytes count 3
98765 12345 Basophils count 22/02/19 10:00 12
87654 12345 monocytes count 21/02/19 11:00 34
76543 12345 lymphocytes count 21/02/19 11:44 35
所需输出
result_table_id order_id event verified_dt_tm result_value
98765 12345 Basophils count 22/02/19 11:00 12
87654 12345 monocytes count 21/02/19 15:00 34
76543 12345 lymphocytes count 21/02/19 14:44 35
76542 12345 rbcytes count 35
下面是示例查询。 此外,欢迎提出更好的查询建议:
select o.order_id
,TO_CHAR(r_o.verified_dt_tm, 'DD-MON-YYYY HH24:MI:SS') as verified_dt_tm
,r_o.result_val as result
,r_o.result_table_id
,omf_get_cv_display(r_o.event_cd) as event
,omf_get_cv_display(o.ORDER_STATUS_CD) as order_status
from orders o
left outer join (select * from results r where r.event_cd > 0
and r.VERIFIED_DT_TM = (select max(COALESCE(r1.VERIFIED_DT_TM,to_date('12/31/2099','mm/dd/yyyy'))) from result r1 where r.ORDER_ID = r1.ORDER_ID
and r.EVENT_CD = r1.event_cd))r_o on r_o.ORDER_ID = o.order_id
ROW_NUMBER
应该在这里可行:
WITH cte AS (
SELECT res.*,
ROW_NUMBER() OVER (PARTITION BY res.order_id, res.event
ORDER BY res.verified_dt_tm DESC, res.result_value DESC) rn
FROM orders o
INNER JOIN result res
ON o.order_id = r.order_id
)
SELECT *
FROM cte
WHERE rn = 1;
根据示例数据,@ Tim的上一个答案是完美的。 但是,如果该有创纪录的事件为“rbcytes计数”的一个具有非空verified_dt_tm
那么也就会给输出与空verified_dt_tm
为空值被递减首先考虑秩序。
查询应基于由verified_dt_tm desc nulls last
的顺序计算ROW_NUMBER。
以下应该为您工作:
WITH CTE AS (
SELECT
RES.*,
ROW_NUMBER() OVER(
PARTITION BY RES.ORDER_ID, RES.EVENT
ORDER BY
RES.VERIFIED_DT_TM DESC NULLS LAST, -- added NULLS LAST
RES.RESULT_VALUE DESC
) RN
FROM
ORDERS O
INNER JOIN RESULT R ON O.ORDER_ID = R.ORDER_ID
)
SELECT
*
FROM
CTE
WHERE
RN = 1;
干杯!!
除上述答案外,如果有人需要将其用作内联子查询的左连接,则:
left outer join (SELECT r.RESULT_VAL
,r.EVENT
,r.result_table_ID
,r.ORDER_ID
,r.VERIFIED_DT_TM
, RANK() OVER(
PARTITION BY r.ORDER_ID,r.EVENT ORDER BY r.VERIFIED_DT_TM DESC NULLS LAST,r.result_table_ID ) AS RANK
from results r )r_o on (r_o.order_id = o.order_id AND r_o.RANK = 1)
如果我理解正确,则可以在Oracle中执行此操作而无需子查询。 尽管语法有点笨拙,但是Oracle在聚合中支持“第一”功能:
select max(r.result_table_id) keep (dense_rank first order by r.verified_dt_tm desc),
r.order_id, r.event,
max(r.verified_dt_tm),
max(r.value) keep (dense_rank first order by r.verified_dt_tm desc, r.result_table_id desc) as value
from orders o join
results r
on o.order_id = r.order_id
group by r.order_id, r.event;
从性能的角度来看,为此目的使用keep
可以取得良好的效果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.