假设我的表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
答案 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