oracle 条件通过失败列SQL

yyhrrdl8  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(93)

输入:
表1
| ID|类别|
| --|--|
| 1 |螺柱|
| 2 |螺柱|
| 3 |螺柱|
表2
| ID|日期|
| --|--|
| 1 |2023年9月30日|
| 1 |2019 -09- 29 2019 -09- 29 2019 -09 - 29|
| 2 |2019 -09- 29 2019 -09- 29 2019 -09 - 29|
| 2 |2023年9月28日|
| 3 |2019 -08- 21 10:00:00|
表3:
| ID|日期|
| --|--|
| 1 |2023年9月30日|
| 1 |2019 -09- 29 2019 -09- 29 2019 -09 - 29|
| 1 |2019 -08- 29 2019 -08- 29|
| 2 |2023年9月28日|
| 3 |2019 -07- 22 2019 - 07 - 22|
输出
| ID|日期|结果|
| --|--|--|
| 1 |2023年9月30日|通过|
| 1 |2019 -08- 29 2019 -08- 29|通过|
| 2 |2019 -09- 29 2019 -09- 29 2019 -09 - 29|通过|
| 3 |2019 -08- 21 10:00:00|失败|
目的:为了基于3个输入表创建输出表,逻辑是为每个id获取每个月的最后一条记录,每个id分别给出id和日期(日期列将从表2而不是表3中提取),因为id 2没有月的最后一天,即9月30日,我选择给定数据中可用的最后一天。
如果“id”在表2或表3中有过去20天的日期条目,则“result”列被框定为“pass”,否则学生的结果为不及格,例如,id 3在表2和表3中都没有过去20天的日期条目,因此result为不及格,而其他两个id的结果为通过

bvhaajcl

bvhaajcl1#

这实际上与your previous question相同;但是,您只需要使用UNION ALL来连接表:

SELECT t1.id,
       t2.date_column,
       CASE
       WHEN t2.date_column >= TRUNC(SYSDATE) - INTERVAL '10' DAY
       THEN 'pass'
       ELSE 'fail'
       END AS result
FROM   table1 t1
       LEFT OUTER JOIN (
         SELECT id,
                date_column,
                ROW_NUMBER() OVER (
                  PARTITION BY id, TRUNC(date_column, 'MM')
                  ORDER BY date_column DESC
                ) AS rn
         FROM   (
           SELECT *
           FROM   table2
         UNION ALL
           SELECT *
           FROM   table3
         )
       ) t2
       ON (t1.id = t2.id AND t2.rn = 1)

其中,对于样本数据:

CREATE TABLE table1 (id) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL;

CREATE TABLE table2 (id, date_column) AS
SELECT 1, TRUNC(SYSDATE) -  9 FROM DUAL UNION ALL
SELECT 1, TRUNC(SYSDATE) - 10 FROM DUAL UNION ALL
SELECT 2, TRUNC(SYSDATE) - 10 FROM DUAL UNION ALL
SELECT 2, TRUNC(SYSDATE) - 11 FROM DUAL UNION ALL
SELECT 3, TRUNC(SYSDATE) - 20 FROM DUAL UNION ALL
SELECT 3, TRUNC(SYSDATE) - 52 FROM DUAL;

CREATE TABLE table3 (id, date_column) AS
SELECT 1, TRUNC(SYSDATE) -  9 FROM DUAL UNION ALL
SELECT 1, TRUNC(SYSDATE) - 10 FROM DUAL UNION ALL
SELECT 2, TRUNC(SYSDATE) - 10 FROM DUAL UNION ALL
SELECT 2, TRUNC(SYSDATE) - 11 FROM DUAL UNION ALL
SELECT 3, TRUNC(SYSDATE) - 18 FROM DUAL;

输出:
| ID|日期_列|结果|
| --|--|--|
| 1 |2019 -04 - 22 00:00:00|通过|
| 2 |2019 -03 - 12 00:00:00|通过|
| 3 |2019 -08-22 00:00:00|失败|
| 3 |2023-09-25 00:00:00|失败|
如果你愿意,你可以通过预过滤表来减少连接的行(你需要测试这对性能的影响,因为它可能会有所帮助,也可能会阻止SQL引擎应用优化,并可能降低性能;我们没有你的表/索引/数据,所以无法测试):

SELECT t1.id,
       t2.date_column,
       CASE
       WHEN t2.date_column >= TRUNC(SYSDATE) - INTERVAL '10' DAY
       THEN 'pass'
       ELSE 'fail'
       END AS result
FROM   table1 t1
       LEFT OUTER JOIN (
         SELECT id,
                date_column,
                ROW_NUMBER() OVER (
                  PARTITION BY id, TRUNC(date_column, 'MM')
                  ORDER BY date_column DESC
                ) AS union_rn
         FROM   (
           SELECT id, date_column
           FROM   (
             SELECT id,
                    date_column,
                    ROW_NUMBER() OVER (
                      PARTITION BY id, TRUNC(date_column, 'MM')
                      ORDER BY date_column DESC
                    ) AS rn
             FROM   table2
           )
           WHERE rn = 1
         UNION ALL
           SELECT id, date_column
           FROM   (
             SELECT id,
                    date_column,
                    ROW_NUMBER() OVER (
                      PARTITION BY id, TRUNC(date_column, 'MM')
                      ORDER BY date_column DESC
                    ) AS rn
             FROM   table3
           )
           WHERE rn = 1
         )
       ) t2
       ON (t1.id = t2.id AND t2.union_rn = 1)

它给出相同的输出。
除了使用ROW_NUMBER,你还可以使用以下方法来查找值:

  • MAX(date_column)GROUP BY id, TRUNC(date_column, 'MM');或
  • 可能LATERALid值加入,并使用FETCH FIRST ROW [ONLY|WITH TIES]来获取最新日期(但每个月可能不那么容易获得)。

fiddle

相关问题