如何避免两个最大的SQL语句?

时间:2019-02-05 09:07:51

标签: sql oracle

我有以下查询要执行,但仍然在一个SQL语句中有两个Max。我想纠正这个问题。

SELECT * FROM persons s INNER JOIN   ( 
  SELECT s1.person_id, 
         MAX(s1.run_number * power(2,64)  + s1.transaction_id) as CEILING_ID, 
         MAX(message_sequence) as MSG_SEQUENCE  
  FROM persons S1 
  WHERE s1.run_number * power(2,64) + s1.transaction_id < 2497 * power(2,64) + 172 
  GROUP BY s1.person_id 
) m ON s.person_id = m.person_id AND 
       s.run_number * power(2,64) + s.transaction_id = m.CEILING_ID 
WHERE s.person_id = 'L1001001' AND 
      s.status != '2' AND 
      s.MESSAGE_SEQUENCE = m.MSG_SEQUENCE

谢谢

1 个答案:

答案 0 :(得分:1)

如果transaction_id总是小于POWER(2,64),那么您似乎正在为最近的message_sequencerun_number找到最大的transaction_id,可以写它使用以下分析功能:

Oracle设置

CREATE TABLE persons ( person_id, run_number, transaction_id, message_sequence, status ) AS
SELECT 'L1001001', 1, 1, 1, 1 FROM DUAL UNION ALL
SELECT 'L1001001', 1, 2, 2, 1 FROM DUAL UNION ALL
SELECT 'L1001001', 2, 1, 3, 1 FROM DUAL UNION ALL
SELECT 'L1001001', 2, 2, 5, 1 FROM DUAL UNION ALL
SELECT 'L1001001', 2, 3, 4, 1 FROM DUAL;

查询

SELECT *
FROM   (
  SELECT p.*,
         MAX( message_sequence )
           KEEP ( DENSE_RANK LAST ORDER BY run_number, transaction_id )
           OVER ( PARTITION BY person_id )
           AS message_for_max_rn_ti,
         MAX( message_sequence )
           OVER ( PARTITION BY person_id )
           AS max_message_sequence
  FROM   persons p
  WHERE  person_id = 'L1001001'
  AND    (  run_number < 2497
         OR ( run_number = 2497 AND transaction_id < 172 ) )
)
WHERE message_sequence = max_message_sequence
AND   status != 2;

输出

PERSON_ID | RUN_NUMBER | TRANSACTION_ID | MESSAGE_SEQUENCE | STATUS | MESSAGE_FOR_MAX_RN_TI | MAX_MESSAGE_SEQUENCE
:-------- | ---------: | -------------: | ---------------: | -----: | --------------------: | -------------------:
L1001001  |          2 |              2 |                5 |      1 |                     4 |                    5

db <>提琴here