Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.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
Sql 在oracle中获得第二个和第四个星期六以及上个月的所有星期日_Sql_Oracle_Date Arithmetic - Fatal编程技术网

Sql 在oracle中获得第二个和第四个星期六以及上个月的所有星期日

Sql 在oracle中获得第二个和第四个星期六以及上个月的所有星期日,sql,oracle,date-arithmetic,Sql,Oracle,Date Arithmetic,我有以下查询,其中列出了上个月的第二个和第四个星期六以及上个月的所有星期日: SELECT to_char(NEXT_DAY(NEXT_DAY(NEXT_DAY(NEXT_DAY(TRUNC((SELECT LAST_DAY(ADD_MONTHS(sysdate,-1)) FROM DUAL), 'MONTH') - 1, 'SATURDAY'), 'SATURDAY'),'SATURDAY'),'SATURDAY'),'YYYYMMDD') SECOND_SATURDAY FROM DUAL

我有以下查询,其中列出了上个月的第二个和第四个星期六以及上个月的所有星期日:

SELECT to_char(NEXT_DAY(NEXT_DAY(NEXT_DAY(NEXT_DAY(TRUNC((SELECT LAST_DAY(ADD_MONTHS(sysdate,-1)) FROM DUAL), 'MONTH') - 1, 'SATURDAY'), 'SATURDAY'),'SATURDAY'),'SATURDAY'),'YYYYMMDD') SECOND_SATURDAY 
FROM DUAL
UNION ALL
SELECT to_char(NEXT_DAY(NEXT_DAY(TRUNC((SELECT LAST_DAY(ADD_MONTHS(sysdate,-1)) FROM DUAL), 'MONTH') - 1, 'SATURDAY'),'SATURDAY'),'YYYYMMDD') SECOND_SATURDAY 
FROM DUAL
UNION ALL
select distinct day_date from
(SELECT to_char(NEXT_DAY(LEVEL + TRUNC((SELECT LAST_DAY(ADD_MONTHS(sysdate,-1)) FROM DUAL), 'MONTH') - 1,'SUNDAY'),'YYYYMMDD') day_date
FROM DUAL
CONNECT BY LEVEL <=  ADD_MONTHS(TRUNC((SELECT LAST_DAY(ADD_MONTHS(sysdate,-1)) FROM DUAL), 'MONTH'), 1) - TRUNC((SELECT LAST_DAY(ADD_MONTHS(sysdate,-1)) FROM DUAL), 'MONTH'))
where substr(day_date,1,6) in (select to_char((SELECT LAST_DAY(ADD_MONTHS(sysdate,-1)) FROM DUAL),'YYYYMM') from dual)

但我觉得必须有一种更简单的方法才能在oracle中获得相同的结果。欢迎在这方面提供任何帮助。我对日期格式的要求是“YYYYMMDD”。

例如:

with 
  t1 as (select add_months(trunc(sysdate, 'month'), -1) dt from dual),
  t2 as (
    select dt + level - 1 dt, to_char(dt + level - 1, 'dy', 'nls_date_language=english') dy
      from t1 connect by dt + level - 1 < trunc(sysdate, 'month'))
select to_char(dt, 'yyyymmdd') dt, dy
  from (
    select dt, dy, sum(case when dy = 'sat' then 1 end) over (order by dt) sm from t2)
  where dy = 'sun' or (dy = 'sat' and sm in (2, 4))
select to_char(dt, 'yyyymmdd') dt
  from (
    select dt, dn, rank() over (order by mod(dn, 6), dt) rnk
      from (
        select d + level - 1 dt, d + level - trunc(d + level - 1, 'iw') dn
          from (select add_months(trunc(sysdate, 'month'), -1) d from dual)
          connect by level <= add_months(d, 1) - d))
  where dn = 7 or (dn = 6 and rnk in (2, 4)) 
我生成了上个月的所有日期,指定了英语日名称,有条件地计算了周六,只显示了有趣的日期

编辑:


这是可行的,但是有没有办法绕过with子句呢 父查询是from:的,其中x为。。。。需要填写日期的地方 天和。因此,它呈现了一种嵌套的情况

是的,您可以轻松地将其转换,例如:

with 
  t1 as (select add_months(trunc(sysdate, 'month'), -1) dt from dual),
  t2 as (
    select dt + level - 1 dt, to_char(dt + level - 1, 'dy', 'nls_date_language=english') dy
      from t1 connect by dt + level - 1 < trunc(sysdate, 'month'))
select to_char(dt, 'yyyymmdd') dt, dy
  from (
    select dt, dy, sum(case when dy = 'sat' then 1 end) over (order by dt) sm from t2)
  where dy = 'sun' or (dy = 'sat' and sm in (2, 4))
select to_char(dt, 'yyyymmdd') dt
  from (
    select dt, dn, rank() over (order by mod(dn, 6), dt) rnk
      from (
        select d + level - 1 dt, d + level - trunc(d + level - 1, 'iw') dn
          from (select add_months(trunc(sysdate, 'month'), -1) d from dual)
          connect by level <= add_months(d, 1) - d))
  where dn = 7 or (dn = 6 and rnk in (2, 4)) 

with子句使步骤更具可读性。现在我还使用了日数和mod进行计数,只是为了展示不同的方法,但是你可以使用更清晰的日名,sum或count代替rank。

例如:

with 
  t1 as (select add_months(trunc(sysdate, 'month'), -1) dt from dual),
  t2 as (
    select dt + level - 1 dt, to_char(dt + level - 1, 'dy', 'nls_date_language=english') dy
      from t1 connect by dt + level - 1 < trunc(sysdate, 'month'))
select to_char(dt, 'yyyymmdd') dt, dy
  from (
    select dt, dy, sum(case when dy = 'sat' then 1 end) over (order by dt) sm from t2)
  where dy = 'sun' or (dy = 'sat' and sm in (2, 4))
select to_char(dt, 'yyyymmdd') dt
  from (
    select dt, dn, rank() over (order by mod(dn, 6), dt) rnk
      from (
        select d + level - 1 dt, d + level - trunc(d + level - 1, 'iw') dn
          from (select add_months(trunc(sysdate, 'month'), -1) d from dual)
          connect by level <= add_months(d, 1) - d))
  where dn = 7 or (dn = 6 and rnk in (2, 4)) 
我生成了上个月的所有日期,指定了英语日名称,有条件地计算了周六,只显示了有趣的日期

编辑:


这是可行的,但是有没有办法绕过with子句呢 父查询是from:的,其中x为。。。。需要填写日期的地方 天和。因此,它呈现了一种嵌套的情况

是的,您可以轻松地将其转换,例如:

with 
  t1 as (select add_months(trunc(sysdate, 'month'), -1) dt from dual),
  t2 as (
    select dt + level - 1 dt, to_char(dt + level - 1, 'dy', 'nls_date_language=english') dy
      from t1 connect by dt + level - 1 < trunc(sysdate, 'month'))
select to_char(dt, 'yyyymmdd') dt, dy
  from (
    select dt, dy, sum(case when dy = 'sat' then 1 end) over (order by dt) sm from t2)
  where dy = 'sun' or (dy = 'sat' and sm in (2, 4))
select to_char(dt, 'yyyymmdd') dt
  from (
    select dt, dn, rank() over (order by mod(dn, 6), dt) rnk
      from (
        select d + level - 1 dt, d + level - trunc(d + level - 1, 'iw') dn
          from (select add_months(trunc(sysdate, 'month'), -1) d from dual)
          connect by level <= add_months(d, 1) - d))
  where dn = 7 or (dn = 6 and rnk in (2, 4)) 
with子句使步骤更具可读性。现在我也使用了日数和mod进行计数,只是为了展示不同的方法,但是你可以使用对你来说更清楚的日名,总和或计数,而不是排名。

编辑,因为我误解了这个问题:

我认为您需要以下内容:

SELECT TO_CHAR(my_date, 'YYYYMMDD') AS my_formatted_date
  FROM (
    SELECT NEXT_DAY(LAST_DAY(ADD_MONTHS(SYSDATE, -2))+7, 'SATURDAY') AS my_date
      FROM dual
     UNION ALL
    SELECT NEXT_DAY(LAST_DAY(ADD_MONTHS(SYSDATE, -2))+21, 'SATURDAY')
      FROM dual
     UNION ALL
    SELECT NEXT_DAY(LAST_DAY(ADD_MONTHS(SYSDATE, -2)), 'SUNDAY') + (LEVEL-1)*7
      FROM dual
   CONNECT BY NEXT_DAY(LAST_DAY(ADD_MONTHS(SYSDATE, -2)), 'SUNDAY') + (LEVEL-1)*7 < TRUNC(SYSDATE, 'MONTH')
);
编辑,因为我误解了问题:

我认为您需要以下内容:

SELECT TO_CHAR(my_date, 'YYYYMMDD') AS my_formatted_date
  FROM (
    SELECT NEXT_DAY(LAST_DAY(ADD_MONTHS(SYSDATE, -2))+7, 'SATURDAY') AS my_date
      FROM dual
     UNION ALL
    SELECT NEXT_DAY(LAST_DAY(ADD_MONTHS(SYSDATE, -2))+21, 'SATURDAY')
      FROM dual
     UNION ALL
    SELECT NEXT_DAY(LAST_DAY(ADD_MONTHS(SYSDATE, -2)), 'SUNDAY') + (LEVEL-1)*7
      FROM dual
   CONNECT BY NEXT_DAY(LAST_DAY(ADD_MONTHS(SYSDATE, -2)), 'SUNDAY') + (LEVEL-1)*7 < TRUNC(SYSDATE, 'MONTH')
);

这是可行的,但有没有办法绕过with子句,因为我的父查询是from:WITHX as。。。。其中日期以所需天数和。所以它呈现了一个嵌套的with情况。这是可行的,但有没有办法绕过with子句,因为我的父查询是from:with x as。。。。其中日期以所需天数和。所以它呈现了一个嵌套的情况,这里的星期六是本月的。我想我必须使用SYSDATE,-2而不是SYSDATE,-1Hi@katipra,我想我误解了你的问题。是的,使用ADD_MONTHSSYSDATE,-2而不是ADD_MONTHSSYSDATE,-1来获得所需的答案。这里的星期六是当月的。我想我必须使用SYSDATE,-2而不是SYSDATE,-1Hi@katipra,我想我误解了你的问题。是的,使用ADD_MONTHSSYSDATE,-2而不是ADD_MONTHSSYSDATE,-1来获得所需的答案。