sql查询仅获取两个日期之间的星期五日期

sql查询仅获取两个日期之间的星期五日期,sql,oracle,Sql,Oracle,问题:在oracle中,如何仅在两个日期之间选择星期五日期 SELECT dates,TO_CHAR(dates,'day-mon-yyyy') FROM (SELECT to_date('01-jan-12','dd-mon-yy')+rownum -1 AS dates FROM addresses WHERE rownum <= to_date('31-jan-12','dd-mon-yy')- to_date('01-jan-12','dd-mon-yy')+1) WH

问题:在oracle中,如何仅在两个日期之间选择星期五日期

 SELECT dates,TO_CHAR(dates,'day-mon-yyyy')
 FROM
 (SELECT to_date('01-jan-12','dd-mon-yy')+rownum -1 AS dates
  FROM addresses
 WHERE rownum <= to_date('31-jan-12','dd-mon-yy')- to_date('01-jan-12','dd-mon-yy')+1)
WHERE upper(regexp_substr(TO_CHAR(dates,'day-mon-yy'),'([[:alpha:]])+'))=upper('FRIDAY');
我需要像这样的输出:

06-JAN-12 FRIDAY 13-JAN-12 FRIDAY 20-JAN-12 FRIDAY 27-JAN-12 FRIDAY 03-FEB-12 FRIDAY 10-FEB-12 FRIDAY 17-FEB-12 FRIDAY 24-FEB-12 FRIDAY 02-MAR-12 FRIDAY 09-MAR-12 FRIDAY 16-MAR-12 FRIDAY 23-MAR-12 FRIDAY 30-MAR-12 FRIDAY
访问更多sql查询:

您将从发布的内容中得到一个错误,因为您用作to_char的第一个参数的值没有包含在单引号中:

select to_date(01-jan-12,'dd-mon-yy') from dual;

ORA-00904: "JAN": invalid identifier
因为没有引号,jan被解释为标识符,并且在addresses表中可能没有列调用jan。使用两位数的年份也是一种不好的做法,如果您必须从非常旧的数据中获取数据,那么使用RR通常比YY更好。月份名称也受NLS设置的影响,因此使用月份编号比使用月份名称更安全;如果确实需要名称,那么to_char函数有第三个参数来控制语言

这是以一种非常复杂的方式进行的,并且依赖于addresses表有足够的行。通过day而不是day指定日期名称的小写形式,然后将其改为大写形式,然后去掉字符串中的位-这是您首先指定的只获取日期名称,然后在假设NLS设置将为您提供英文日期名称的情况下进行比较是。。。不必要的复杂。正如对固定字符串文本调用upper一样,您可以并且已经提供了大写字母

而不是

WHERE upper(regexp_substr(TO_CHAR(dates,'day-mon-yy'),'([[:alpha:]])+'))=upper('FRIDAY');
您可以执行以下任一操作或其他变体:

WHERE regexp_substr(TO_CHAR(dates,'DAY-mon-
y'),'([[:alpha:]])+')=upper('FRIDAY');
WHERE TO_CHAR(dates,'DAY')='FRIDAY   ';
WHERE TRIM(TO_CHAR(dates,'DAY'))=upper('FRIDAY');
WHERE TO_CHAR(dates,'FMDAY','NLS_DATE_LANGUAGE=ENGLISH')='FRIDAY';
通过对双表使用分层查询,可以避免依赖addresses表:

正如@mathguy在一篇评论中指出的,虽然“下一天”是NLS敏感的,但您可以使用表达式作为第二个参数,因此您可以这样做,而不是硬编码日期名称:

next_day(date '2012-01-01' - 1, to_char(date '1999-12-31', 'FMDAY'))
其中1999-12-31可以是任何已知为星期五的日期;如果您不介意select列表和connect by子句中的表达式是不同的,那么您-和我-不应该!您可以通过以下方法降低该检查的计算成本:

SELECT dates, to_char(dates, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH')
FROM (
  SELECT next_day(date '2012-01-01' - 1,
    to_char(date '1999-12-31', 'FMDAY')) + (7 * (level - 1)) AS dates
  FROM dual
  CONNECT BY level <= 1 + (date '2012-03-31' - next_day(date '2012-01-01' - 1,
    to_char(date '1999-12-31', 'FMDAY')))/7
);

无论会话的日期语言如何,它都会获得与上面相同的13行。如果您希望输出也使用会话语言,只需将覆盖的第三个参数删除为to_char。

请阅读您的问题/问题/错误是什么?您显示的内容需要在日期字符串周围加上单引号,作为开始,但是。。。看起来很复杂,addresses表的相关性是什么?Thanq u非常好,我忘记了单引号,现在它运行良好。使用次日的解决方案可能是最有效的。为了使其独立于调用会话的语言,我们可以计算某个日期的“Day”,即已知的某个日期为星期五,然后在调用下一个日期时使用该日期。同样的解决方案可以通过解决connect中的level不等式来提高效率,也就是说,将其写成level@mathguy-huh,出于某种原因,我认为下一天的第二个参数必须是文字而不是表达式;不知道我从哪里得到的,因为这显然不是真的。还同意将计算转移到RHS以提高效率;为了可读性,在connectby中使用与select列表相同的表达式可能会有所帮助,但是这里的成本差异可能很大,因此在这种情况下,这不是一个令人信服的论点。谢谢
next_day(date '2012-01-01' - 1, to_char(date '1999-12-31', 'FMDAY'))
SELECT dates, to_char(dates, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH')
FROM (
  SELECT next_day(date '2012-01-01' - 1,
    to_char(date '1999-12-31', 'FMDAY')) + (7 * (level - 1)) AS dates
  FROM dual
  CONNECT BY level <= 1 + (date '2012-03-31' - next_day(date '2012-01-01' - 1,
    to_char(date '1999-12-31', 'FMDAY')))/7
);