如果第一个条件满足执行它,否则在 Oracle 中的第二个条件
If first condition satisfies perform it, otherwise second condition in Oracle
我正在尝试从 table 中按状态获取员工。我有 2 个状态,如果员工有 A 条件,则取该行,否则取 P 最大状态行 oper_day 如下所示:
Table
---------------------------------------------------
id | emp_code | name | status | oper_day |
--------------------------------------------------
1 | 164094 | John | P | 2020-10-02 |
2 | 164094 | John | P | 2020-10-09 |
3 | 164094 | John | A | 2020-10-10 |
4 | 145890 | Mike | P | 2020-10-05 |
我的结果应该如下所示
--------------------------------
id | emp_code | name | status | oper_day |
--------------------------------------------------
1 | 164094 | John | A | 2020-10-10 |
2 | 145890 | Mike | P | 2020-10-05 |
感谢任何帮助
使用ROW_NUMBER
:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY emp_code ORDER BY status, oper_day DESC) rn
FROM yourTable t
)
SELECT id, emp_code, name, status, oper_day
FROM cte
WHERE rn = 1;
这里的逻辑是,如果员工有状态 A
记录,它将被分配到第一个行号,因为 A
在 P
之前排序。否则,将选择 P
状态记录。如果有多个记录,我们会为每个员工选择较新的记录。
您可以将聚合函数与 KEEP( DENSE_RANK FIRST ORDER BY ... )
:
一起使用
SELECT MAX( id ) KEEP ( DENSE_RANK FIRST ORDER BY status ASC, oper_day DESC ) AS id,
emp_code,
MAX( name ),
MIN( status ) AS status,
MAX( oper_day ) KEEP ( DENSE_RANK FIRST ORDER BY status ) AS oper_day
FROM table_name
GROUP BY
emp_code
其中,对于您的示例数据:
CREATE TABLE table_name ( id, emp_code, name, status, oper_day ) AS
SELECT 1, 164094, 'John', 'P', DATE '2020-10-02' FROM DUAL UNION ALL
SELECT 2, 164094, 'John', 'P', DATE '2020-10-09' FROM DUAL UNION ALL
SELECT 3, 164094, 'John', 'A', DATE '2020-10-10' FROM DUAL UNION ALL
SELECT 4, 145890, 'Mike', 'P', DATE '2020-10-05' FROM DUAL;
输出:
ID | EMP_CODE | MAX(NAME) | STATUS | OPER_DAY
-: | -------: | :-------- | :----- | :------------------
4 | 145890 | Mike | P | 2020-10-05 00:00:00
3 | 164094 | John | A | 2020-10-10 00:00:00
db<>fiddle here
我正在尝试从 table 中按状态获取员工。我有 2 个状态,如果员工有 A 条件,则取该行,否则取 P 最大状态行 oper_day 如下所示:
Table
---------------------------------------------------
id | emp_code | name | status | oper_day |
--------------------------------------------------
1 | 164094 | John | P | 2020-10-02 |
2 | 164094 | John | P | 2020-10-09 |
3 | 164094 | John | A | 2020-10-10 |
4 | 145890 | Mike | P | 2020-10-05 |
我的结果应该如下所示
--------------------------------
id | emp_code | name | status | oper_day |
--------------------------------------------------
1 | 164094 | John | A | 2020-10-10 |
2 | 145890 | Mike | P | 2020-10-05 |
感谢任何帮助
使用ROW_NUMBER
:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY emp_code ORDER BY status, oper_day DESC) rn
FROM yourTable t
)
SELECT id, emp_code, name, status, oper_day
FROM cte
WHERE rn = 1;
这里的逻辑是,如果员工有状态 A
记录,它将被分配到第一个行号,因为 A
在 P
之前排序。否则,将选择 P
状态记录。如果有多个记录,我们会为每个员工选择较新的记录。
您可以将聚合函数与 KEEP( DENSE_RANK FIRST ORDER BY ... )
:
SELECT MAX( id ) KEEP ( DENSE_RANK FIRST ORDER BY status ASC, oper_day DESC ) AS id,
emp_code,
MAX( name ),
MIN( status ) AS status,
MAX( oper_day ) KEEP ( DENSE_RANK FIRST ORDER BY status ) AS oper_day
FROM table_name
GROUP BY
emp_code
其中,对于您的示例数据:
CREATE TABLE table_name ( id, emp_code, name, status, oper_day ) AS
SELECT 1, 164094, 'John', 'P', DATE '2020-10-02' FROM DUAL UNION ALL
SELECT 2, 164094, 'John', 'P', DATE '2020-10-09' FROM DUAL UNION ALL
SELECT 3, 164094, 'John', 'A', DATE '2020-10-10' FROM DUAL UNION ALL
SELECT 4, 145890, 'Mike', 'P', DATE '2020-10-05' FROM DUAL;
输出:
ID | EMP_CODE | MAX(NAME) | STATUS | OPER_DAY -: | -------: | :-------- | :----- | :------------------ 4 | 145890 | Mike | P | 2020-10-05 00:00:00 3 | 164094 | John | A | 2020-10-10 00:00:00
db<>fiddle here