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 SUN,
SUM(DECODE(WDAY, '2', MDAY, NULL)) AS MON,
SUM(DECODE(WDAY, '3', MDAY, NULL)) AS TUE,
SUM(DECODE(WDAY, '4', MDAY, NULL)) AS WED,
SUM(DECODE(WDAY, '5', MDAY, NULL)) AS THU,
SUM(DECODE(WDAY, '6', MDAY, NULL)) AS FRI,
SUM(DECODE(WDAY, '7', MDAY, NULL)) AS SAT
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')))
GROUP BY MON, MON_NAME, NEW_YWEEK;
但是以上是将星期日作为一周的第一天,我想将星期一作为一周的第一天,如下所示,谢谢!
答案 0 :(得分:1)
您可以通过以下操作更简单地做到这一点:
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_start_of_week列更改为trunc(dt + 1, 'iw') - 1 dt_start_of_week
,并将这些列的别名从mon-sun更改为sun-sat。
这可以通过找到等周起始日(始终是星期一)来实现。然后,您可以使用它进行分组,并在其上加上row_number分析函数以查找该行的月份中的星期几。
答案 1 :(得分:0)
TO_CHAR(DAYOFYEAR, 'd')
的值取决于NLS_TERRITORY参数的值。
您有2个选择:
选项1
将NLS_TERRITORY参数设置为将星期一视为第一天的值(例如“ UNITED KINGDOM”),然后执行以下查询(SUM(DECODE(WDAY,
已调整):
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;
选项2
请勿触摸NLS_TERRITORY参数并在下面的查询中执行({SUM(DECODE(WDAY,
已调整,并且WDAY
的值的计算方式已更改):
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;