如何从所有列表中选择第一个条目
How to pick the first entry out of all the list
本次测试table,数据如下。即使有多少条目,也需要选择当天的第一个有效记录。
还有,那一天rank no可能会增加
A
B
STATUS
LOAD_DATE
RANKNO
SAMPLE
SAMPLE
VALID
10-Jan-22
3
SAMPLE
SAMPLE
INVALID
10-Jan-22
5
SAMPLE
SAMPLE
VALID
10-Jan-22
6 **
SAMPLE
SAMPLE
VALID
1-Jan-22
10
SAMPLE
SAMPLE
INVALID
1-Jan-22
12
SAMPLE
SAMPLE
INVALID
1-Jan-22
12
2022 年 1 月 10 日的预期输出是,行:
A
B
STATUS
LOAD_DATE
RANKNO
SAMPLE
SAMPLE
VALID
10-Jan-22
6 **
我们可以 select * from test where rankno = 6
(这是针对 22 年 1 月 10 日的)但是 22 年 1 月 11 日可能只有 2 条记录,我们需要选择最高 rankno
如果我用Load_date查询,它应该获取具有最高排名的有效记录。
SELECT A, B, Status, load_date
FROM test
WHERE status = 'VALID'
AND ....
或者我们可以吗?
SELECT max(rankno)
FROM test
WHERE load_date = '10-JAN-22'
以下查询将 return 蓝色行。
FETCH FIRST 1 ROWS ONLY
return仅根据指定的 ORDER BY 的第一行。
SELECT
A, B, Status,
load_date,
RANKNO,
ROWNUM
FROM test
WHERE status = 'VALID'
ORDER BY
load_date ASC,
RANKNO DESC
fetch first 1 rows only;
见https://dbfiddle.uk/?rdbms=oracle_18&fiddle=793f06cc4a3d7ea6e978eb683ce3d095
这里我们在子查询中使用 RANK() 来获取外部查询中需要的行。
create table test (
A varchar(10),
B varchar(10),
STATUS VARCHAR (10),
LOAD_DATE date,
RANKNO int);
✓
INSERT INTO test (A,B,STATUS,LOAD_DATE,RANKNO)
SELECT 'SAMPLE','SAMPLE','VALID',TO_DATE('2022-01-01', 'yyyy-mm-dd'),3 FROM DUAL UNION ALL
SELECT 'SAMPLE','SAMPLE','INVALID',TO_DATE('2022-01-01', 'yyyy-mm-dd'),5 FROM DUAL UNION ALL
SELECT 'SAMPLE','SAMPLE','VALID',TO_DATE('2022-01-01', 'yyyy-mm-dd') ,6 FROM DUAL UNION ALL
SELECT 'SAMPLE','SAMPLE','VALID',TO_DATE('2022-01-10', 'yyyy-mm-dd'),10 FROM DUAL UNION ALL
SELECT 'SAMPLE','SAMPLE','INVALID',TO_DATE('2022-01-10', 'yyyy-mm-dd'),12 FROM DUAL UNION ALL
SELECT 'SAMPLE','SAMPLE','INVALID',TO_DATE('2022-01-10', 'yyyy-mm-dd'),14 FROM DUAL
6 行受影响
SELECT * FROM
(SELECT
A, B, Status,
load_date ,
ROWNUM,
RANKNO,
RANK() OVER (
ORDER BY load_date ASC,
RANKNO DESC) rnk
FROM test
WHERE
status = 'VALID'
--AND ROWNUM = 1
ORDER BY
load_date ASC,
RANKNO DESC)s
WHERE rnk = 1;
A | B | STATUS | LOAD_DATE | ROWNUM | RANKNO | RNK
:----- | :----- | :----- | :-------- | -----: | -----: | --:
SAMPLE | SAMPLE | VALID | 01-JAN-22 | 2 | 6 | 1
db<>fiddle here
本次测试table,数据如下。即使有多少条目,也需要选择当天的第一个有效记录。 还有,那一天rank no可能会增加
A | B | STATUS | LOAD_DATE | RANKNO | |
---|---|---|---|---|---|
SAMPLE | SAMPLE | VALID | 10-Jan-22 | 3 | |
SAMPLE | SAMPLE | INVALID | 10-Jan-22 | 5 | |
SAMPLE | SAMPLE | VALID | 10-Jan-22 | 6 ** | |
SAMPLE | SAMPLE | VALID | 1-Jan-22 | 10 | |
SAMPLE | SAMPLE | INVALID | 1-Jan-22 | 12 | |
SAMPLE | SAMPLE | INVALID | 1-Jan-22 | 12 |
2022 年 1 月 10 日的预期输出是,行:
A | B | STATUS | LOAD_DATE | RANKNO |
---|---|---|---|---|
SAMPLE | SAMPLE | VALID | 10-Jan-22 | 6 ** |
我们可以 select * from test where rankno = 6
(这是针对 22 年 1 月 10 日的)但是 22 年 1 月 11 日可能只有 2 条记录,我们需要选择最高 rankno
如果我用Load_date查询,它应该获取具有最高排名的有效记录。
SELECT A, B, Status, load_date
FROM test
WHERE status = 'VALID'
AND ....
或者我们可以吗?
SELECT max(rankno)
FROM test
WHERE load_date = '10-JAN-22'
以下查询将 return 蓝色行。
FETCH FIRST 1 ROWS ONLY
return仅根据指定的 ORDER BY 的第一行。
SELECT
A, B, Status,
load_date,
RANKNO,
ROWNUM
FROM test
WHERE status = 'VALID'
ORDER BY
load_date ASC,
RANKNO DESC
fetch first 1 rows only;
见https://dbfiddle.uk/?rdbms=oracle_18&fiddle=793f06cc4a3d7ea6e978eb683ce3d095
这里我们在子查询中使用 RANK() 来获取外部查询中需要的行。
create table test ( A varchar(10), B varchar(10), STATUS VARCHAR (10), LOAD_DATE date, RANKNO int);
✓
INSERT INTO test (A,B,STATUS,LOAD_DATE,RANKNO) SELECT 'SAMPLE','SAMPLE','VALID',TO_DATE('2022-01-01', 'yyyy-mm-dd'),3 FROM DUAL UNION ALL SELECT 'SAMPLE','SAMPLE','INVALID',TO_DATE('2022-01-01', 'yyyy-mm-dd'),5 FROM DUAL UNION ALL SELECT 'SAMPLE','SAMPLE','VALID',TO_DATE('2022-01-01', 'yyyy-mm-dd') ,6 FROM DUAL UNION ALL SELECT 'SAMPLE','SAMPLE','VALID',TO_DATE('2022-01-10', 'yyyy-mm-dd'),10 FROM DUAL UNION ALL SELECT 'SAMPLE','SAMPLE','INVALID',TO_DATE('2022-01-10', 'yyyy-mm-dd'),12 FROM DUAL UNION ALL SELECT 'SAMPLE','SAMPLE','INVALID',TO_DATE('2022-01-10', 'yyyy-mm-dd'),14 FROM DUAL
6 行受影响
SELECT * FROM (SELECT A, B, Status, load_date , ROWNUM, RANKNO, RANK() OVER ( ORDER BY load_date ASC, RANKNO DESC) rnk FROM test WHERE status = 'VALID' --AND ROWNUM = 1 ORDER BY load_date ASC, RANKNO DESC)s WHERE rnk = 1;
A | B | STATUS | LOAD_DATE | ROWNUM | RANKNO | RNK :----- | :----- | :----- | :-------- | -----: | -----: | --: SAMPLE | SAMPLE | VALID | 01-JAN-22 | 2 | 6 | 1
db<>fiddle here