【问题标题】:Find last finish task using oracle sql使用 oracle sql 查找最后完成的任务
【发布时间】:2021-12-27 13:19:44
【问题描述】:

我需要在每个组中使用 sql 找到最后完成的任务。我有两个条件。 construction_type = 0construction_type in (1, 2)。对于construction_type = 0。只会获取已完成的任务。但是对于construction_type in (1, 2)。可以获取已完成和未完成的任务。我进行了查询,但问题是如果任务完成并且输入了一些未完成的新任务,那么这个未完成的任务将排在最前面。我尝试了不同的顺序,但不知何故无法获得最后完成的任务,以防万一 construction_type in (1, 2)construction_type = 0 没有问题,因为只会获取已完成的任务。

我将在 task_last_modified_date 之前订购。如果一些新任务将进入,那么它具有最高的 task_last_modified_date。这就是为什么我的未完成任务排在首位的原因。它应该类似于latest task_last_modified_date with completed task。但我不知道该怎么做。

这是样本数据

CREATE TABLE project_complete_data (CONSTRUCTION_TYPE, PROJECT_ID, PROJ_COMPANY_NAME,   CUSTOM_LOT_NO, LOT_STATUS, SCHEDULE_TASK_ID, TASK_NAME, TASK_STATUS, TASK_ACTUAL_END_DATE, TASK_FINISH_DATE, TASK_FINISHED, TASK_LAST_MODIFIED_DATE, PO_TOTAL_AMOUNT, PO_STATUS, PO_TYPE) AS
          SELECT 1, 511, 'Amber Hills Inc.', '0000000077', 102, 10961162, 'electrical rough',                     101, DATE '2021-12-13', DATE '2021-11-19', 0, TO_DATE('2021-11-16 14:44:04', 'YYYY-MM-DD hh24:mi:ss'),    49.7, 100, 101  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '0000000077', 102, 10961161, 'plumbing rough',                       101, DATE '2021-12-06', DATE '2021-11-12', 1, TO_DATE('2021-11-15 15:22:13', 'YYYY-MM-DD hh24:mi:ss'),    0.3,  101, 101  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '0000000077', 102, 10961159, 'roof framing',                         101, DATE '2021-11-29', DATE '2021-11-15', 1, TO_DATE('2021-11-15 13:04:37', 'YYYY-MM-DD hh24:mi:ss'),    10,   101, 101  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '0000000077', 102, 10961158, 'second floor framing',                 101, DATE '2021-11-15', DATE '2021-11-09', 1, TO_DATE('2021-11-09 15:22:42', 'YYYY-MM-DD hh24:mi:ss'),    50,   101, 101  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '0000000077', 102, 10961157, 'first floor framing',                  101, DATE '2021-11-08', DATE '2021-11-09', 1, TO_DATE('2021-11-09 14:44:57', 'YYYY-MM-DD hh24:mi:ss'),    0,    101, 101  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '0000000077', 102, 10961157, 'first floor framing',                  101, DATE '2021-11-08', DATE '2021-11-09', 1, TO_DATE('2021-11-09 14:44:57', 'YYYY-MM-DD hh24:mi:ss'),    0,    101, 101  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '01a',        103, 10134563, 'Rough-In Plumbing',                    101, DATE '2009-12-17', DATE '2014-09-01', 1, NULL,                                                       0,    100, 100  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '02',         103, 2213016,  'Update Lender Info in BT - Sales Rep', 101, DATE '2005-06-28', DATE '2005-10-11', 1, NULL,                                                       0,    100, 100  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '020',        103, 10955239, 'TK task',                              101, DATE '2018-11-07', DATE '2019-06-21', 1, TO_DATE('2019-06-21 18:12:21', 'YYYY-MM-DD hh24:mi:ss'),    0,    100, 101  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', '020',        103, 10955239, 'TK task',                              101, DATE '2018-11-07', DATE '2019-06-21', 1, TO_DATE('2019-06-21 18:12:21', 'YYYY-MM-DD hh24:mi:ss'),    33,   100, 100  FROM DUAL
UNION ALL SELECT 1, 511, 'Amber Hills Inc.', 'testpa01',   102, 10959716, 'HVAC rough',                           101, DATE '2021-09-17', DATE '2021-09-15', 0, TO_DATE('2021-11-02 12:28:57', 'YYYY-MM-DD hh24:mi:ss'),    0,    101, 100  FROM DUAL;

这里是查询

select 
    proj_company_name, 
    custom_lot_no,
    task_name,
    task_actual_end_date,                           
    task_finish_date,
    task_finished,
    task_last_modified_date,
    to_char(task_last_modified_date, 'YYYY-MM-DD hh24:mi:ss') AS TASK_LAST_MODIFIED_DATE_TIME,
    ROW_NUMBER() OVER (PARTITION BY custom_lot_no ORDER BY to_char(task_last_modified_date, 'YYYY-MM-DD hh24:mi:ss') desc) AS LAST_TASK_FINISH_SEQ,
    po_total_amount,
    po_status,
    CASE 
        WHEN po_status = 101 THEN po_total_amount   
        ELSE 0
    END as POs_COMPLETED,
    po_type,
    CASE 
        WHEN po_type = 100 THEN po_total_amount 
        ELSE 0
    END as "COMMITTED"
FROM project_complete_data
where project_id = 511
AND po_status in ('100', '101')
AND lot_status in ('102', '103')
And task_status = 101
AND (
        (construction_type = 0 AND task_finished = 1 and (schedule_task_id is not null or schedule_task_id > 0))    
        OR (construction_type in ('1', '2') AND task_finished in ('1', '0'))                
) 
order by custom_lot_no, to_char(task_last_modified_date, 'YYYY-MM-DD hh24:mi:ss') desc;

此查询给出以下结果

如您所见,最高记录的 last_modified_date_time 最高,它在 last_task_finish_seq 的 1 处出现。但此任务未完成,因为它的 task_finished is 0。所以第一条记录应该是第二条记录,因为尽管它 last_modified_date_time 较少但已完成。它在最后完成,因为它的 last_modified_date_time 比其他完成的任务更高。

我该怎么做?实际上,在获得每个组记录之后,我会使用类似的东西

`select * from (above query) where LAST_TASK_FINISH_SEQ = 1;`

因为那时我知道我在每个组的顶部都有最后完成的任务。

谢谢

【问题讨论】:

  • 如果将AND task_finished in ('1', '0') 替换为AND task_finished ='1' 会发生什么?
  • @Nick 我不能,因为在这两种情况下我都会完成任务。但是在construction_type in ('1', '2') 的情况下,我输入了AND task_finished in ('1', '0'),所以两个任务都来了。已完成和未完成
  • 如果您想首先只考虑已完成的任务和完成日期的订单,请使用ROW_NUMBER .... ORDER BY TASK_FINISHED desc, to_char(task_last_modified_date, 'YYYY-MM-DD hh24:mi:ss') desc
  • 我想我刚刚想通了。如果我使用ROW_NUMBER() OVER (PARTITION BY custom_lot_no, task_finished ORDER BY to_char(task_last_modified_date, 'YYYY-MM-DD hh24:mi:ss') desc) AS LAST_TASK_FINISH_SEQ,。然后我将在每组中有两个分区。一种用于Finished tasks,另一种用于Unfinished tasks。然后我可以简单地使用select * from (above query) where LAST_TASK_FINISH_SEQ = 1 and task_finished = 1。现在我将从每个组中获取最后完成的任务。

标签: sql oracle oracle-sqldeveloper


【解决方案1】:

要获取最近完成的行(或最新的行,如果没有行完成并且construction_type IN (1,2)),您可以使用:

SELECT *
FROM   (
  SELECT *
  FROM   project_complete_data
  WHERE  project_id = 511
  AND    po_status IN (100, 101)
  AND    lot_status IN (102, 103)
  AND    task_status = 101
  AND    (  (   construction_type = 0
            AND task_finished = 1
            AND schedule_task_id IS NOT NULL)
         OR construction_type IN (1, 2)
         )
)
MATCH_RECOGNIZE (
  PARTITION BY custom_lot_no
  ORDER     BY task_finished DESC, task_last_modified_date DESC
  ALL ROWS PER MATCH
  PATTERN ( ^ latest_finished_row )
  DEFINE
    latest_finished_row AS 1 = 1
)

如果您想在不过滤的情况下对行进行排序:

select proj_company_name, 
       custom_lot_no,
       task_name,
       task_actual_end_date,                           
       task_finish_date,
       task_finished,
       task_last_modified_date,
       to_char(task_last_modified_date, 'YYYY-MM-DD hh24:mi:ss')
         AS TASK_LAST_MODIFIED_DATE_TIME,
       ROW_NUMBER() OVER (
         PARTITION BY custom_lot_no
         ORDER BY task_finished DESC, task_last_modified_date desc
       ) AS LAST_TASK_FINISH_SEQ,
       po_total_amount,
       po_status,
       CASE 
       WHEN po_status = 101
       THEN po_total_amount   
       ELSE 0
       END as POs_COMPLETED,
       po_type,
       CASE 
       WHEN po_type = 100
       THEN po_total_amount 
       ELSE 0
       END as "COMMITTED"
FROM   project_complete_data
where  project_id = 511
AND    po_status  in (100, 101)
AND    lot_status in (102, 103)
And    task_status = 101
AND    (  (   construction_type = 0
          AND task_finished = 1 
          AND schedule_task_id is not null
          )    
       OR (   construction_type in (1, 2)
          AND task_finished in (1, 0)
          ) 
) 
order by custom_lot_no, task_last_modified_date desc;

db小提琴here

【讨论】:

    猜你喜欢
    • 2021-10-19
    • 2014-01-18
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    相关资源
    最近更新 更多