有没有一种方法可以对值进行分组,只获取验证特定条件的值?

Is there a way to group values getting only the ones that verifies certain condition?

我正在尝试在 Oracle SQL 中编写一个查询,该查询通过一些 ID 聚合值,其中我有以下 table 作为输入:

ID SOME_DATE RANK_POSITION
301 20211201 1
301 20211202 2
301 20211203 3
649 20211201 1
649 20211202 2
649 20211206 3
649 20211208 4
649 20211211 5
758 20211212 1
758 20211222 2

你想获得这样的东西:

ID FIRST_IN_RANK_DATE SECOND_IN_RANK_DATE
301 01/12/2021 02/12/2021
649 01/12/2021 02/12/2021
758 12/12/2021 22/12/2021

其中 FIRST_IN_RANK_DATERANK_POSITION 中第一个日期 IDSECOND_IN_RANK_DATE 是 [=11] 中第二个日期=] 对于特定的 ID.

您可以使用条件聚合:

SELECT id,
       MAX(CASE rank_position WHEN 1 THEN some_date END) AS first_in_rank_date,
       MAX(CASE rank_position WHEN 2 THEN some_date END) AS second_in_rank_date
FROM   table_name
GROUP BY id

PIVOT:

SELECT *
FROM   table_name
PIVOT (
  MAX(some_date)
  FOR rank_position IN (
    1 AS first_in_rank_date,
    2 AS second_in_rank_date
  )
)

或者,从 Oracle 12,MATCH_RECOGNIZE

SELECT *
FROM   table_name
MATCH_RECOGNIZE (
  PARTITION BY id
  ORDER     BY rank_position
  MEASURES
    rank1.some_date AS first_in_rank_date,
    rank2.some_date AS second_in_rank_date
  PATTERN ( ^ rank1 rank2 )
  DEFINE
    rank1 AS rank_position = 1,
    rank2 AS rank_position = 2
)

其中,对于示例数据:

CREATE TABLE table_name (ID, SOME_DATE, RANK_POSITION) AS
SELECT 301, DATE '2021-12-01', 1 FROM DUAL UNION ALL
SELECT 301, DATE '2021-12-02', 2 FROM DUAL UNION ALL
SELECT 301, DATE '2021-12-03', 3 FROM DUAL UNION ALL
SELECT 649, DATE '2021-12-01', 1 FROM DUAL UNION ALL
SELECT 649, DATE '2021-12-02', 2 FROM DUAL UNION ALL
SELECT 649, DATE '2021-12-06', 3 FROM DUAL UNION ALL
SELECT 649, DATE '2021-12-08', 4 FROM DUAL UNION ALL
SELECT 649, DATE '2021-12-11', 5 FROM DUAL UNION ALL
SELECT 758, DATE '2021-12-12', 1 FROM DUAL UNION ALL
SELECT 758, DATE '2021-12-22', 2 FROM DUAL;

全部输出:

ID FIRST_IN_RANK_DATE SECOND_IN_RANK_DATE
301 2021-12-01 00:00:00 2021-12-02 00:00:00
649 2021-12-01 00:00:00 2021-12-02 00:00:00
758 2021-12-12 00:00:00 2021-12-22 00:00:00

db<>fiddle here