如何使用Oracle SQL创建日历
我可以使用以下脚本创建日历: 但是上面是把星期天作为一周的第一天,我想把星期一作为一周的第一天,如下,如何做,谢谢如何使用Oracle SQL创建日历,sql,oracle,Sql,Oracle,我可以使用以下脚本创建日历: 但是上面是把星期天作为一周的第一天,我想把星期一作为一周的第一天,如下,如何做,谢谢 您可以更简单地执行以下操作: WITH dts AS (SELECT TRUNC(to_date('&year', 'yyyy'), 'yyyy') + LEVEL -1 AS dt FROM dual CONNECT BY LEVEL <= to_char(TO_DATE(&YEAR || '1231
您可以更简单地执行以下操作:
WITH dts AS (SELECT TRUNC(to_date('&year', 'yyyy'), 'yyyy') + LEVEL -1 AS dt
FROM dual
CONNECT BY LEVEL <= to_char(TO_DATE(&YEAR || '1231', 'yyyymmdd'), 'ddd')),
dts2 AS (SELECT dt,
TRUNC(dt, 'mm') dt_mon,
TRUNC(dt, 'iw') dt_start_of_week,
to_char(dt, 'fmdd') day_of_month
FROM dts)
SELECT to_char(dt_mon, 'fmMonth') "MONTH",
row_number() OVER (PARTITION BY to_char(dt_mon, 'fmMonth') ORDER BY dt_start_of_week) week_num,
MAX(CASE WHEN dt = dt_start_of_week THEN day_of_month END) mon,
MAX(CASE WHEN dt = dt_start_of_week + 1 THEN day_of_month END) tue,
MAX(CASE WHEN dt = dt_start_of_week + 2 THEN day_of_month END) wed,
MAX(CASE WHEN dt = dt_start_of_week + 3 THEN day_of_month END) thu,
MAX(CASE WHEN dt = dt_start_of_week + 4 THEN day_of_month END) fri,
MAX(CASE WHEN dt = dt_start_of_week + 5 THEN day_of_month END) sat,
MAX(CASE WHEN dt = dt_start_of_week + 6 THEN day_of_month END) sun
FROM dts2
GROUP BY dt_mon,
to_char(dt_mon, 'fmMonth'),
dt_start_of_week
ORDER BY dt_mon, dt_start_of_week;
如果希望一周以星期日开始,则可以在dts2子查询中将“每周的dt_开始”列更改为truncdt+1,“iw'-1每周的dt_开始”,以及将列的别名从mon sun更改为sun-sat
这是通过查找iso周开始日来实现的,该日始终是星期一。然后,您可以使用它来分组,并在其上抛出一个行数分析函数,以查找该行的月数周。to\u CHARDAYOFYEAR,'d'的值取决于NLS\u TERRITORY参数的值
您有两种选择:
选择1
将NLS_TERRITORY参数设置为将星期一视为第一天的值,例如“联合王国”和“执行以下查询SUMDECODEWDAY”,已调整:
ALTER SESSION SET NLS_TERRITORY = 'UNITED KINGDOM';
SELECT CASE
WHEN (NEW_YWEEK = MIN(NEW_YWEEK)
OVER(PARTITION BY MON ORDER BY NEW_YWEEK)) THEN
MON_NAME
ELSE
MON_NAME
END AS MONTH,
-- NEW_YWEEK AS YWEEK,
ROW_NUMBER() OVER(PARTITION BY MON ORDER BY NEW_YWEEK) AS MWEEK,
SUM(DECODE(WDAY, '1', MDAY, NULL)) AS MON,
SUM(DECODE(WDAY, '2', MDAY, NULL)) AS TUE,
SUM(DECODE(WDAY, '3', MDAY, NULL)) AS WED,
SUM(DECODE(WDAY, '4', MDAY, NULL)) AS THU,
SUM(DECODE(WDAY, '5', MDAY, NULL)) AS FRI,
SUM(DECODE(WDAY, '6', MDAY, NULL)) AS SAT,
SUM(DECODE(WDAY, '7', MDAY, NULL)) AS SUN
FROM (SELECT DAYOFYEAR AS EVERYDAY,
TO_CHAR(DAYOFYEAR, 'mm') AS MON,
TO_CHAR(DAYOFYEAR, 'Month') AS MON_NAME,
TO_CHAR(DAYOFYEAR, 'w') AS MWEEK,
TO_CHAR(DAYOFYEAR, 'ww') AS YWEEK,
CASE
WHEN (TO_CHAR(TO_DATE(&YEAR || '0101', 'yyyymmdd'), 'd') > '1') AND
(TO_CHAR(DAYOFYEAR, 'd') <
TO_CHAR(TO_DATE(&YEAR || '0101', 'yyyymmdd'), 'd')) THEN
TO_CHAR(TO_CHAR(DAYOFYEAR, 'ww') + 1, 'fm00')
ELSE
TO_CHAR(DAYOFYEAR, 'ww')
END AS NEW_YWEEK,
TO_CHAR(DAYOFYEAR, 'd') AS WDAY,
/*decode(
TO_CHAR(DAYOFYEAR, 'd') ,
'2','1','3','2','4','3','5','4' ,'6','5','7','6' ,'7' )AS WDAY,*/
TO_CHAR(DAYOFYEAR, 'dd') AS MDAY
FROM (SELECT TO_DATE(&YEAR || '0101', 'yyyymmdd') + LEVEL -1 AS DAYOFYEAR
FROM DUAL
CONNECT BY LEVEL <=
TO_CHAR(TO_DATE(&YEAR || '1231', 'yyyymmdd'),
'ddd'))
--where TO_CHAR(DAYOFYEAR, 'Month') = 'November'
)
GROUP BY MON, MON_NAME, NEW_YWEEK;
顺便说一句,我相信这只是一个简单的删除sumdecowday,'1',MDAY,NULL作为SUN,作为最后一个。。
ALTER SESSION SET NLS_TERRITORY = 'UNITED KINGDOM';
SELECT CASE
WHEN (NEW_YWEEK = MIN(NEW_YWEEK)
OVER(PARTITION BY MON ORDER BY NEW_YWEEK)) THEN
MON_NAME
ELSE
MON_NAME
END AS MONTH,
-- NEW_YWEEK AS YWEEK,
ROW_NUMBER() OVER(PARTITION BY MON ORDER BY NEW_YWEEK) AS MWEEK,
SUM(DECODE(WDAY, '1', MDAY, NULL)) AS MON,
SUM(DECODE(WDAY, '2', MDAY, NULL)) AS TUE,
SUM(DECODE(WDAY, '3', MDAY, NULL)) AS WED,
SUM(DECODE(WDAY, '4', MDAY, NULL)) AS THU,
SUM(DECODE(WDAY, '5', MDAY, NULL)) AS FRI,
SUM(DECODE(WDAY, '6', MDAY, NULL)) AS SAT,
SUM(DECODE(WDAY, '7', MDAY, NULL)) AS SUN
FROM (SELECT DAYOFYEAR AS EVERYDAY,
TO_CHAR(DAYOFYEAR, 'mm') AS MON,
TO_CHAR(DAYOFYEAR, 'Month') AS MON_NAME,
TO_CHAR(DAYOFYEAR, 'w') AS MWEEK,
TO_CHAR(DAYOFYEAR, 'ww') AS YWEEK,
CASE
WHEN (TO_CHAR(TO_DATE(&YEAR || '0101', 'yyyymmdd'), 'd') > '1') AND
(TO_CHAR(DAYOFYEAR, 'd') <
TO_CHAR(TO_DATE(&YEAR || '0101', 'yyyymmdd'), 'd')) THEN
TO_CHAR(TO_CHAR(DAYOFYEAR, 'ww') + 1, 'fm00')
ELSE
TO_CHAR(DAYOFYEAR, 'ww')
END AS NEW_YWEEK,
TO_CHAR(DAYOFYEAR, 'd') AS WDAY,
/*decode(
TO_CHAR(DAYOFYEAR, 'd') ,
'2','1','3','2','4','3','5','4' ,'6','5','7','6' ,'7' )AS WDAY,*/
TO_CHAR(DAYOFYEAR, 'dd') AS MDAY
FROM (SELECT TO_DATE(&YEAR || '0101', 'yyyymmdd') + LEVEL -1 AS DAYOFYEAR
FROM DUAL
CONNECT BY LEVEL <=
TO_CHAR(TO_DATE(&YEAR || '1231', 'yyyymmdd'),
'ddd'))
--where TO_CHAR(DAYOFYEAR, 'Month') = 'November'
)
GROUP BY MON, MON_NAME, NEW_YWEEK;
SELECT CASE
WHEN (NEW_YWEEK = MIN(NEW_YWEEK)
OVER(PARTITION BY MON ORDER BY NEW_YWEEK)) THEN
MON_NAME
ELSE
MON_NAME
END AS MONTH,
-- NEW_YWEEK AS YWEEK,
ROW_NUMBER() OVER(PARTITION BY MON ORDER BY NEW_YWEEK) AS MWEEK,
SUM(DECODE(WDAY, '1', MDAY, NULL)) AS MON,
SUM(DECODE(WDAY, '2', MDAY, NULL)) AS TUE,
SUM(DECODE(WDAY, '3', MDAY, NULL)) AS WED,
SUM(DECODE(WDAY, '4', MDAY, NULL)) AS THU,
SUM(DECODE(WDAY, '5', MDAY, NULL)) AS FRI,
SUM(DECODE(WDAY, '6', MDAY, NULL)) AS SAT,
SUM(DECODE(WDAY, '7', MDAY, NULL)) AS SUN
FROM (SELECT DAYOFYEAR AS EVERYDAY,
TO_CHAR(DAYOFYEAR, 'mm') AS MON,
TO_CHAR(DAYOFYEAR, 'Month') AS MON_NAME,
TO_CHAR(DAYOFYEAR, 'w') AS MWEEK,
TO_CHAR(DAYOFYEAR, 'ww') AS YWEEK,
CASE
WHEN (TO_CHAR(TO_DATE(&YEAR || '0101', 'yyyymmdd'), 'd') > '1') AND
(TO_CHAR(DAYOFYEAR, 'd') <
TO_CHAR(TO_DATE(&YEAR || '0101', 'yyyymmdd'), 'd')) THEN
TO_CHAR(TO_CHAR(DAYOFYEAR, 'ww') + 1, 'fm00')
ELSE
TO_CHAR(DAYOFYEAR, 'ww')
END AS NEW_YWEEK,
DECODE(MOD(TO_CHAR(DAYOFYEAR, 'd')-1, 7), 0,7, TO_CHAR(DAYOFYEAR, 'd')-1) AS WDAY,
/*decode(
TO_CHAR(DAYOFYEAR, 'd') ,
'2','1','3','2','4','3','5','4' ,'6','5','7','6' ,'7' )AS WDAY,*/
TO_CHAR(DAYOFYEAR, 'dd') AS MDAY
FROM (SELECT TO_DATE(&YEAR || '0101', 'yyyymmdd') + LEVEL -1 AS DAYOFYEAR
FROM DUAL
CONNECT BY LEVEL <=
TO_CHAR(TO_DATE(&YEAR || '1231', 'yyyymmdd'),
'ddd'))
--where TO_CHAR(DAYOFYEAR, 'Month') = 'November'
)
GROUP BY MON, MON_NAME, NEW_YWEEK;