选择最早的日期记录-Oracle sql

vh0rcniy  于 2023-06-22  发布在  Oracle
关注(0)|答案(3)|浏览(144)

我对Oracle SQL有疑问,我必须根据日期范围选择最早的记录。我订了A桌
| 符号运行日期|客户编号|客户端_状态|
| - -----|- -----|- -----|
| 2023 - 03 - 31 - 2023 - 2023 - 03 - 31 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 202| 00019872| 2|
| 2023 - 03 - 30 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023 - 2023| 00019872| 2|
| 2023 - 03 - 29| 00019872| 2|
| 2023 - 03 - 28 2023 - 03 - 28 2023 - 03 - 28| 00019872| 2|
| 2023 - 03 - 27 2023 - 03 - 27| 00019872| 1|
| 2023 - 03 - 26 2023 - 03 - 26| 00019872| 1|
| 2023 - 03 - 25 2023 - 03 - 25 2023 - 03 - 25| 00019872| 1|
| 2023 - 03 - 24 2023 - 03 - 24| 00019872| 2|
| 2023 - 03 - 23 - 2023 - 03 - 23| 00019872| 2|
| 2023 - 03 - 22 2023 - 03 - 22 2023 - 03 - 22| 00019872| 2|
| 2023 - 03 - 21 2023 - 03 - 21 2023 - 03 - 21| 00019872| 2|
| 2023 - 03 - 20 2023 - 03 - 20 2023 - 03 - 20| 00019872| 2|
| 2023 - 03 - 19 2023 - 03 - 19 2023 - 03 - 19| 00019872| 2|
| 2023 - 03 - 18 2023 - 03 - 18 2023 - 03 - 18| 00019872| 1|
| 2023 - 03 - 17| 00019872| 1|
| 2023 - 03 - 16 2023 - 03 - 16 2023 - 03 - 16| 00019872| 1|
我的结果输出应该是(CLIENT_STATUS = 2)
| 符号运行日期|客户编号|客户端_状态|
| - -----|- -----|- -----|
| 2023 - 03 - 28 2023 - 03 - 28 2023 - 03 - 28| 00019872| 2|
请让我知道它如何可以实现在oracle sql

r6hnlfcb

r6hnlfcb1#

如果你想要最早的一行包含最新的client_status,那么使用MATCH_RECOGNIZE来执行逐行处理:

SELECT *
FROM   table_name
MATCH_RECOGNIZE(
  ORDER BY sym_run_date DESC
  ALL ROWS PER MATCH
  PATTERN (^ {- (same_status*) -} next_row )
  DEFINE same_status AS client_status = NEXT(client_status)
)

或者,使用解析函数:

SELECT SYM_RUN_DATE,
       CLIENT_NO,
       CLIENT_STATUS
FROM   (
  SELECT SYM_RUN_DATE,
         CLIENT_NO,
         CLIENT_STATUS,
         ROW_NUMBER() OVER (ORDER BY sym_run_date DESC)
           - ROW_NUMBER() OVER (PARTITION BY client_status ORDER BY sym_run_date DESC) AS grp
  FROM   table_name
)
WHERE   grp = 0
ORDER BY sym_run_date
FETCH FIRST ROW ONLY;

其中,对于样本数据:

CREATE TABLE table_name (SYM_RUN_DATE, CLIENT_NO, CLIENT_STATUS) AS
SELECT DATE '2023-03-31', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-30', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-29', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-28', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-27', '00019872', 1 FROM DUAL UNION ALL
SELECT DATE '2023-03-26', '00019872', 1 FROM DUAL UNION ALL
SELECT DATE '2023-03-25', '00019872', 1 FROM DUAL UNION ALL
SELECT DATE '2023-03-24', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-23', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-22', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-21', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-20', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-19', '00019872', 2 FROM DUAL UNION ALL
SELECT DATE '2023-03-18', '00019872', 1 FROM DUAL UNION ALL
SELECT DATE '2023-03-17', '00019872', 1 FROM DUAL UNION ALL
SELECT DATE '2023-03-16', '00019872', 1 FROM DUAL;

两个输出:
| 符号运行日期|客户编号|客户端_状态|
| - -----|- -----|- -----|
| 2019 -03-28 00:00:00| 00019872| 2|
fiddle

ef1yzkbh

ef1yzkbh2#

我不是特别喜欢这种方法,但-目前,不能想出更好的办法。
样本数据:

SQL> select * From test order by sym_run_date desc;

SYM_RUN_DA CLIENT_N CLIENT_STATUS
---------- -------- -------------
2023-03-31 00019872             2
2023-03-30 00019872             2
2023-03-29 00019872             2
2023-03-28 00019872             2
2023-03-27 00019872             1
2023-03-26 00019872             1
2023-03-25 00019872             1
2023-03-24 00019872             2
2023-03-23 00019872             2

9 rows selected.

temp CTE查找每个客户端的最高日期,状态= 1,而主查询返回日期大于CTE返回的日期且状态= 2的行。

SQL> with temp as
  2    (select client_no, max(sym_run_date) sym_run_date
  3     from test
  4     where client_status = 1
  5     group by client_no
  6    )
  7  select a.client_no, min(a.sym_run_date) sym_run_date, a.client_status
  8  from test a join temp b on a.client_no = b.client_no
  9  where a.sym_run_date > b.sym_run_date
 10    and a.client_status = 2
 11  group by a.client_no, a.client_status;

CLIENT_N SYM_RUN_DA CLIENT_STATUS
-------- ---------- -------------
00019872 2023-03-28             2

SQL>
wgeznvg7

wgeznvg73#

一个方便的方法是使用row_number()来获得一个与最小日期和日期范围相匹配的单行,例如:

SELECT
      SYM_RUN_DATE
    , CLIENT_NO
    , CLIENT_STATUS
FROM (
    SELECT
          SYM_RUN_DATE
        , CLIENT_NO
        , CLIENT_STATUS
        , row_number() OVER (ORDER BY SYM_RUN_DATE ASC) AS rn
    FROM tablea
    WHERE SYM_RUN_DATE > to_date('2023-03-27')
            AND SYM_RUN_DATE <= to_date('2023-04-23')
    ) d
WHERE rn = 1

在这里,row_number()函数从最早日期的1开始,并对后续的每一行递增1。在外部查询中,我们只要求生成rn为1的行。请注意,order by确定如何生成行编号序列。升序使最早的日期成为第1行,而降序将使最近的日期成为第1行。同样,如果有多个行具有相同的最早日期,则此方法仍将仅返回1行。

相关问题