使用case语句解决oracle查询问题

时间:2013-01-15 03:57:53

标签: oracle case

我有一个物化视图表,其中包含有关员工及其对系统的访问权限的信息  该表有一个“effective_date”列和“effective_date_to列。这个物化视图每晚都会更新一次。

我想在此表中添加一个额外的列“current_flag”,以显示当前员工是否具有“Y”或“N”的访问权限。 我正在考虑使用类似以下内容的“案例”声明: -

CASE WHEN  to_date(c.effective_date) < to_date(sysdate) 
and to_date      (effective_date_to) > to_date(sysdate)
THEN  'Y'
   ELSE 'N'            
END) AS current_flag

这是最好的方法吗?如果是这样,那么正确的语法是什么,因为我正在努力让它发挥作用..

原始物化视图表位于...

之下
CREATE MATERIALIZED VIEW TC.employee_access 

(
EMPL_ID,
EFFECTIVE_DATE,
EFFECTIVE_DATE_TO,
DEPARTMENT,
JOB_DESCRIPTION,
TIME_STAMP,
MODIFIED_BY
)
TABLESPACE TC_TC_DATA
PCTUSED    0
PCTFREE    10
INITRANS   2
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            NEXT             1M
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
NOCACHE
LOGGING
NOCOMPRESS
NOPARALLEL
BUILD IMMEDIATE
REFRESH FORCE
START WITH TO_DATE('16-Jan-2013','dd-mon-yyyy')
NEXT TRUNC(SYSDATE+1)
WITH PRIMARY KEY
AS 

SELECT C.EMPL_ID AS Empl_Id,
       C.EFFECTIVE_DT AS Effective_Date,
       DECODE (n.effective_dt,
               c.effective_dt, TO_DATE ('01/01/2099', 'DD/MM/YYYY'),
               n.effective_dt - 1)
              AS Effective_Date_To,
       C.DFLT_UDT06_ID AS Department,     
       C.DFLT_UDT08_ID AS Job_Description,
       C.TIME_STAMP,
       C.MODIFIED_BY
  FROM empl_history_mv c, empl_history_mv n
 WHERE n.effective_dt =
          (SELECT NVL (MIN (effective_dt), c.effective_dt)
             FROM empl_history_mv
            WHERE empl_id = c.empl_id AND effective_dt > c.effective_dt)
       AND c.empl_id = n.empl_id;

2 个答案:

答案 0 :(得分:0)

除了你拥有的额外支架,以及错误的to_Date()它看起来对我有用。

即。你试过这个吗?

CREATE MATERIALIZED VIEW TC.employee_access 
(
EMPL_ID,
EFFECTIVE_DATE,
EFFECTIVE_DATE_TO,
DEPARTMENT,
JOB_DESCRIPTION,
TIME_STAMP,
MODIFIED_BY,
current_flag
)
...
WITH PRIMARY KEY
AS 

SELECT C.EMPL_ID AS Empl_Id,
       C.EFFECTIVE_DT AS Effective_Date,
       DECODE (n.effective_dt,
               c.effective_dt, TO_DATE ('01/01/2099', 'DD/MM/YYYY'),
               n.effective_dt - 1)
              AS Effective_Date_To,
       C.DFLT_UDT06_ID AS Department,     
       C.DFLT_UDT08_ID AS Job_Description,
       C.TIME_STAMP,
       C.MODIFIED_BY,
       CASE WHEN c.effective_date < sysdate
                 and effective_date_to > sysdate
       THEN  'Y'
       ELSE 'N'            
       END as current_flag
  FROM empl_history_mv c, empl_history_mv n
 ....

答案 1 :(得分:0)

CASE - 语句需要访问您的计算值effective_date_to。您可以使用一组额外的括号来执行此操作:

SELECT empl_id,
       effective_date,
       effective_date_to,
       CASE WHEN effective_date < SYSDATE AND SYSDATE < effective_date_to
            THEN 'Y' ELSE 'N' END current_flag
  FROM (
        SELECT c.empl_id
               c.effective_dt as effective_date,
          FROM ...
       );

或者您将逻辑推广到一个查询中:

SELECT c.empl_id, 
       c.effective_dt as effective_date,
       NVL2(n.effective_dt, n.effective_dt - 1, DATE'2099-01-01') AS effective_date_to,
       CASE WHEN c.effective_dt <= sysdate
             AND (sysdate < n.effective_dt OR n.effective_dt IS NULL) 
            THEN 'Y' ELSE 'N' END AS current_flag
  FROM empl_history_mv c
  LEFT JOIN empl_history_mv n 
    ON c.empl_id = n.empl_id
   AND c.effective_dt < n.effective_dt
   AND NOT EXISTS (
       SELECT * 
         FROM empl_history_mv t
        WHERE c.empl_id = t.empl_id
          AND c.effective_dt < t.effective_dt
          AND t.effective_dt < n.effective_dt
       );