Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Oracle SQL创建日历_Sql_Oracle - Fatal编程技术网

如何使用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;