条件分析函数

时间:2017-10-13 16:38:33

标签: sql oracle

工作:

,MAX(CASE WHEN MAX(HIST)
      AND workid IS NOT NULL 
     AND ROLE = 'red' 
       THEN 'ASSIGNED'
         ELSE 'UNASSIGNED'
         END)
            OVER (PARTITION BY id) AS ASSIGNED 

标准:

按ID分区

使用PKHistid列查看每个ID的最后一个条目

如果Role = Red且Workid在每个ID的最后一个条目中不为NULL

然后分配

其他未分配

表:

PKHistid    ID    Role       Entry_Date    Workid
 1          101    Red       1/1/17         201
 2          101    Yellow    1/2/17         201
 3          102    Yellow    5/1/17        (Null)
 4          102    Red       6/1/17         202
 5          103    Red       7/1/17         202
 6          103    Red       7/5/17         202

预期结果:(新列Assigned_Status)

PKHistid    ID    Role       Entry_Date    Workid    *Assigned_Status
 1          101    Red       1/1/17         201         Unassigned
 2          101    Yellow    1/2/17         201         Unassigned
 3          102    Yellow    5/1/17        (Null)       Assigned
 4          102    Red       6/1/17         202         Assigned
 5          103    Red       7/1/17         202         Assigned
 6          103    Red       7/5/17         202         Assigned

1 个答案:

答案 0 :(得分:1)

这是“而不是”您之前的问题(今天也发布),还是“除了”它?如果它是“除了”之外,请注意您可以在同一查询中执行这两项操作。

在这里,您需要一个case表达式来创建其他列。在case表达式中,条件使用分析函数。我更喜欢LAST函数的分析版本(不幸的是,许多开发人员似乎并不知道和使用它)。如果您不熟悉,请阅读Oracle文档。

请注意,分析函数不能嵌套;但绝对没有禁止在case表达式中使用分析函数。我经常看到在子查询中调用分析函数的解决方案,然后在外部查询中进行进一步处理(例如使用分析函数的结果的case表达式)。不必要的分层!

with
  inputs ( pkhistid, id, role, entry_date, workid) as (
    select 1, 101, 'Red'   , to_date('1/1/17', 'mm/dd/rr'), 201  from dual union all
    select 2, 101, 'Yellow', to_date('1/2/17', 'mm/dd/rr'), 201  from dual union all
    select 3, 102, 'Yellow', to_date('5/1/17', 'mm/dd/rr'), null from dual union all
    select 4, 102, 'Red'   , to_date('6/1/17', 'mm/dd/rr'), 202  from dual union all
    select 5, 103, 'Red'   , to_date('7/1/17', 'mm/dd/rr'), 202  from dual union all
    select 6, 103, 'Red'   , to_date('7/5/17', 'mm/dd/rr'), 202  from dual
  )
-- End of simulated inputs (for testing only, not part of the solution).
-- SQL query begins BELOW THIS LINE. Use your actual table and column names.
select   pkhistid, id, role, entry_date, workid,
         case when max(role)   keep (dense_rank last order by pkhistid)
                               over (partition by id) = 'Red'
                   and
                   max(workid) keep (dense_rank last order by pkhistid)
                               over (partition by id) is not null
              then 'Assigned'
              else 'Unassigned' end as assigned_status
from     inputs
order by id, pkhistid -- If needed
;

  PKHISTID         ID ROLE   ENTRY_DATE     WORKID ASSIGNED_STATUS
---------- ---------- ------ ---------- ---------- ---------------
         1        101 Red    01/01/17          201 Unassigned
         2        101 Yellow 01/02/17          201 Unassigned
         3        102 Yellow 05/01/17              Assigned  
         4        102 Red    06/01/17          202 Assigned  
         5        103 Red    07/01/17          202 Assigned  
         6        103 Red    07/05/17          202 Assigned  
相关问题