Oracle - 如何检查多条记录中的值以及一个值是不是匹配 - 将其用于更大的数据集

Posted

技术标签:

【中文标题】Oracle - 如何检查多条记录中的值以及一个值是不是匹配 - 将其用于更大的数据集【英文标题】:Oracle - How to check values from multiple records and if one values matches - use it for larger datasetOracle - 如何检查多条记录中的值以及一个值是否匹配 - 将其用于更大的数据集 【发布时间】:2020-12-07 10:06:01 【问题描述】:

这是我的数据:

Step   random_task     Status         date
1        do_this      Completed       1-Nov-2020
1        do-that      Cancelled       2-Nov-2020
2        do_this     Not Assigned     1-Nov-2020
2        do_that      Cancelled       2-Nov-2020
2        and_that     Cancelled       2-Nov-2020
3        do_this      Cancelled       2-Nov-2020
3        do_that      Cancelled       2-Nov-2020
3        also_that    Cancelled       2-Nov-2020
4        do_that      In Progress or Scheduled or whatever   1-Nov-2020
4        and_that     Completed       2-Nov-2020

按步骤分组:

已完成 = 如果步骤中的所有任务都具有 APS_Status__c = “已完成”。

已完成 = 如果至少 1 个任务“已完成”且所有剩余任务 =“已取消”。

未开始 = 如果至少 1 个任务“未分配”且所有剩余任务 =“已取消”。

未开始 = 如果步骤中的所有任务都有 APS_Status__c = “未分配”。

Cancelled = 如果步骤中的所有任务都有 APS_Status__c = “Cancelled”。

进行中 = 如果至少有 1 个任务“已完成”或“已取消”或“未分配”。

输出:

Step       Status            date 
1          Completed         2-Nov-2020 (if status = completed, then max(date) of that step
2          Not Started      (null)
3          Cancelled        (null)
4          In Progress      (null)

我尝试将值添加到 100、-100 和 0 之类的值,将其相加,然后提取 mod(sum,100) 以确定正确的值。但我无法为该步骤分配 max(date)。

【问题讨论】:

您是否尝试过自己编写查询? 嗨蒂姆是的,让我编辑并将其添加到我的问题中。 【参考方案1】:

您可以将条件聚合用作:

select step,
       (case when min(status) = max(status) and min(status) in ('Completed', 'Cancelled')
             then min(status)
             when sum(case when status in ('Completed', 'Cancelled') then 1 else 0 end) = count(*)
             then 'Completed'
             when sum(case when status in ('Not Assigned', 'Cancelled') then 1 else 0 end) = count(*)
             then 'Not Started'
             then ''
             else 'In Progress'
       end) as status,
       (case when min(status) = max(status) and min(status) in 'Completed'
             then max(date)
        end)
from t
group by step;

这些稍微简化了您的逻辑。特别是,“已完成”和“已取消”在逻辑中首先处理——如果所有状态都相同。如果所有状态均为“未分配”或“已取消”,则步骤为“未开始”。

【讨论】:

谢谢 Gordon,这很有效,看起来很容易理解。我正在尝试 mod() 然后提取数字等。这要容易得多。【参考方案2】:

您可以按如下方式使用 GROUP BY 和条件聚合:

SELECT STEP, STATUS, CASE WHEN STATUS = 'Completed' THEN DATE END AS DATE FROM
(SELECT STEP,
       DATE,
       CASE WHEN COMPLETED = TOTAL THEN 'Completed' 
            WHEN (COMPLETED >= 1 AND CANCELLED = TOTAL - COMPLETED) 
                 OR (NOTASSIGNED >= 1 AND CANCELLED = TOTAL - NOTASSIGNED) THEN 'Cancelled'
            WHEN NOTASSIGNED = TOTAL THEN 'Not Assigned'
            WHEN CANCELLED = TOTAL THEN 'Cancelled'
        END AS STATUS
FROM
(SELECT STEP,
       COUNT(CASE WHEN STATUS = 'Completed' THEN 1 END) AS COMPLETED,
       COUNT(CASE WHEN STATUS = 'Cancelled' THEN 1 END) AS CANCELLED,
       COUNT(CASE WHEN STATUS = 'Not Assigned' THEN 1 END) AS NOTASSIGNED,
       COUNT(CASE WHEN STATUS = 'In Progress' THEN 1 END) AS INPROGRESS,
       COUNT(1) AS TOTAL,
       MAX(DATE) AS DATE
FROM YOUR_TABLE
GROUP BY STEP))

我不确定 In progress 状态,所以请自行处理。

【讨论】:

以上是关于Oracle - 如何检查多条记录中的值以及一个值是不是匹配 - 将其用于更大的数据集的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 MS Access 2013 中根据另一个表中的值生成多条新记录吗?

Oracle通过一个字段的值将一条记录拆分为多条记录

SQL 查询将多条记录中的值组合到单个列中

检查oracle表单多记录块中的重复值

如何根据Oracle中的值查找表名[重复]

如何使用 , 和 : Oracle 中的分隔符将 CLOB 对象拆分为多条记录