搜索存储逗号分隔值的列值中的值

时间:2016-02-23 10:08:50

标签: oracle

假设我的表XYZ有一个Weekend_Days列存储了值SUNDAY,SATURDAY,我有另一个表ABC,日期为ACT_DATE,可以是任何日期。现在我必须检查这一天的日期是否是一个周末。

我尝试使用:

select  ACT_DATE
,       case 
            when UPPER(TO_CHAR(ACT_DATE,'DAY')) IN (SELECT Weekend_Days from XYZ) 
               then 1 
            else 0 
        end as Weekend_Flag 
from ABC

但它不起作用,它只是在所有日期返回0。

尝试将Weekend_Days的值存储为('SUNDAY','SATURDAY'),但它不起作用。

示例数据:

表XYZ:

WEEKEND_DAYS
---------------
SUNDAY,SATURDAY

表ABC:

ACT_DATE
---------
02-Feb-16
06-Feb-16

当前结果:

ACT_DATE  WEEKEND_FLAG
--------- ------------
02-Feb-16            0
06-Feb-16            0

预期结果:

ACT_DATE  WEEKEND_FLAG
--------- ------------
02-Feb-16            0
06-Feb-16            1

2 个答案:

答案 0 :(得分:0)

Oracle安装程序

CREATE OR REPLACE FUNCTION split_String(
  i_str    IN  VARCHAR2,
  i_delim  IN  VARCHAR2 DEFAULT ','
) RETURN SYS.ODCIVARCHAR2LIST DETERMINISTIC
AS
  p_result       SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST();
  p_start        NUMBER(5) := 1;
  p_end          NUMBER(5);
  c_len CONSTANT NUMBER(5) := LENGTH( i_str );
  c_ld  CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
  IF c_len > 0 THEN
    p_end := INSTR( i_str, i_delim, p_start );
    WHILE p_end > 0 LOOP
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
      p_start := p_end + c_ld;
      p_end := INSTR( i_str, i_delim, p_start );
    END LOOP;
    IF p_start <= c_len + 1 THEN
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
    END IF;
  END IF;
  RETURN p_result;
END;
/

CREATE TABLE xyz ( weekend_days ) AS
SELECT 'SATURDAY,SUNDAY' FROM DUAL;

CREATE TABLE abc ( act_date ) AS
SELECT DATE '2016-02-02' FROM DUAL UNION ALL
SELECT DATE '2016-02-06' FROM DUAL;

<强>查询

SELECT act_date,
       CASE WHEN w.Weekend_day IS NULL THEN 0 ELSE 1 END AS weekend_flag
FROM  abc a
      LEFT OUTER JOIN
      ( SELECT t.column_value AS weekend_day
        FROM   xyz x,
               TABLE( split_String( x.weekend_days ) ) t
      ) w
      ON TRIM( TO_CHAR( a.ACT_DATE, 'DAY' ) ) = w.Weekend_day;

<强>输出

ACT_DATE  WEEKEND_FLAG
--------- ------------
06-FEB-16            1 
02-FEB-16            0 

替代查询

SELECT act_date,
       CASE
         WHEN INSTR( x.weekend_days, TRIM( TO_CHAR( act_date, 'DAY' ) ) ) > 0
         THEN 1
         ELSE 0
         END AS weekend_flag
FROM   abc a
       CROSS JOIN
       xyz x;

这将提供相同的输出,并且适用于天的名称,但不适用于一般情况,因为您可能会得到与子字符串的误报匹配。

答案 1 :(得分:-1)

<强>更新

由于我没有在第一条路上理解OP问题,所以这是现在应该有用的新陈述!

SELECT
ACT_DATE,
CASE
WHEN UPPER(DATENAME(DW, ACT_DATE)) IN ( SELECT LEFT(Weekend_Days, CHARINDEX(',', Weekend_days + ',') - 1) AS Sat FROM @XYZ
                                        UNION ALL
                                        SELECT STUFF(Weekend_Days, 1, CHARINDEX(',', Weekend_Days + ','), '') AS Sun FROM @XYZ)
    THEN 1
    ELSE 0
END AS Weekend_flag
FROM @ABC

<强> OLD:

SELECT
ACT_DATE,
CASE
WHEN UPPER(DATENAME(DW, ACT_DATE)) IN (SELECT Weekend_Days FROM XYZ)
    THEN 1
    ELSE 0
END AS Weekend_flag
FROM ABC

您可以使用方法&#34; DATENAME&#34;来获取星期几。间隔时间&#34;周 - dw&#34;给出。参考:http://www.techonthenet.com/sql_server/functions/datename.php

希望这有帮助!

修改

OP表示IN功能不起作用。好吧,我用虚拟数据尝试了它,对我来说它正在工作。这是我的虚假陈述:

DECLARE @XYZ Table(Weekend_Days varchar(255))
DECLARE @ABC Table(ACT_DATE datetime)

INSERT INTO @XYZ VALUES('SAMSTAG')
INSERT INTO @XYZ VALUES('SONNTAG')

INSERT INTO @ABC VALUES('02-Feb-16')
INSERT INTO @ABC VALUES('03-Feb-16')
INSERT INTO @ABC VALUES('04-Feb-16')
INSERT INTO @ABC VALUES('05-Feb-16')
INSERT INTO @ABC VALUES('06-Feb-16')
INSERT INTO @ABC VALUES('07-Feb-16')
INSERT INTO @ABC VALUES('08-Feb-16')
INSERT INTO @ABC VALUES('09-Feb-16')
INSERT INTO @ABC VALUES('10-Feb-16')
INSERT INTO @ABC VALUES('11-Feb-16')
INSERT INTO @ABC VALUES('12-Feb-16')
INSERT INTO @ABC VALUES('13-Feb-16')
INSERT INTO @ABC VALUES('14-Feb-16')
INSERT INTO @ABC VALUES('15-Feb-16')
INSERT INTO @ABC VALUES('16-Feb-16')

SELECT
ACT_DATE,
CASE
    WHEN UPPER(DATENAME(DW, ACT_DATE)) IN (SELECT Weekend_Days FROM @XYZ)
    THEN 1
    ELSE 0
END AS Weekend_flag
FROM @ABC

我的结果如下:

ACT_DATE    Weekend_flag
2016-02-23 11:37:48.810 0
2016-02-02 00:00:00.000 0
2016-02-03 00:00:00.000 0
2016-02-04 00:00:00.000 0
2016-02-05 00:00:00.000 0
2016-02-06 00:00:00.000 1
2016-02-07 00:00:00.000 1
2016-02-08 00:00:00.000 0
2016-02-09 00:00:00.000 0
2016-02-10 00:00:00.000 0
2016-02-11 00:00:00.000 0
2016-02-12 00:00:00.000 0
2016-02-13 00:00:00.000 1
2016-02-14 00:00:00.000 1
2016-02-15 00:00:00.000 0
2016-02-16 00:00:00.000 0