【问题标题】:Find only particular days between two dates仅查找两个日期之间的特定日期
【发布时间】:2013-02-05 01:59:19
【问题描述】:

我有一个包含如下数据的 Oracle 表:

 1. ID           DATE 
 2. 12           02/11/2013
 3. 12           02/12/2013
 4. 13           02/11/2013
 5. 13           02/12/2013
 6. 13           02/13/2013
 7. 13           02/14/2013
 8. 14           02/11/2013
 9. 14           02/12/2013
10. 14           02/13/2013

我只需要找到那些只有星期一、星期二和星期三日期的 ID,所以这里应该只返回 ID = 14。我正在使用 Oracle,日期格式为 MM/DD/YYYY。 请指教。

问候, 尼丁

【问题讨论】:

  • 您的日期是真实日期(按数据类型)还是格式为 MM/DD/YYYY 的字符串?
  • 在处理 SQL 时,如果您给我们一些代码来创建您所拥有的表而不是 ASCII 表转储,通常会有所帮助。

标签: oracle date date-math


【解决方案1】:

如果日期列是 DATE 数据类型,那么您可以

select id
from your_table
group by id
having sum(case 
           when to_char(date_col,'fmday') 
                in ('monday','tuesday','wednesday') then 1
           else 99
           end) = 3;

编辑在igr的观察中更正了上面的代码

但这只有在你没有一天两次使用同一个 id 时才可以。

如果列是 varchar2 则条件变为to_char(to_date(your_col,'mm/dd/yyyy'),'fmday') in ...

更健壮的代码是:

select id 
from(
    select id, date_col
    from your_table
    group by id, date_col
)
group by id
having sum(case 
           when to_char(date_col,'fmday', 'NLS_DATE_LANGUAGE=ENGLISH') 
                    in ('monday','tuesday','wednesday') then 1
           else 99
           end) = 3;

【讨论】:

  • 此解决方案不取决于您使用的语言设置吗?
  • 这不重要,也不是用户的问题。他只想知道如何选择具有该属性的 id。
  • 不幸的是,系统之间的设置会有所不同。因此,如果有一个不依赖于这些设置的解决方案,请使用它。总是。
  • 你的例子没有消除 id=13
  • @FlorinGhita 您需要将掩码添加为 fmday 而不是 day 否则星期一/星期二会填充空白,因此永远不会匹配您的 in 子句,或者只使用 dymon tue等..
【解决方案2】:
select id 
from (
  select 
     id, 
     sum (case when to_char(dt, 'D', 'nls_territory=AMERICA') between 1 and 3 then 1 else -1 end) AS cnt
  from t
  group by id
)
where cnt=3

注意:我假设 (id,dt) 是唯一的 - 没有两行具有相同的 id 和日期。

【讨论】:

  • 星期一是一周的第一天就可以了。这取决于 nls_territory。
  • @igr,你还需要在内部选择一个group by id
  • 感谢您的两个建议 - 我做了更改。
【解决方案3】:

做类似的事情

SELECT * FROM your_table t 
      where to_char(t.DATE, 'DY') in ('whatever_day_abbreviation_day_you_use');

或者,如果您愿意,也可以使用以下日期数字:

SELECT * FROM your_table t 
     where  to_number(to_char(d.ts, 'D')) in (1,2,3);

如果您想避免 ID 重复,请添加 DISTINCTION

SELECT DISTINCT ID FROM your_table t 
     where  to_number(to_char(d.ts, 'D')) in (1,2,3);

【讨论】:

  • 这些也将返回 id: 12, 13
  • 您的条件是“...只有周一、周二和周三的日期”;那么 2/11 和 2/12 是星期一和星期二...
  • 是OP条件,不是我的。再次阅读他的要求。他想要那些只有三天的身份证。不只是两天,也不是另一个不同的日子。
  • 此外,D 的值取决于 NLS_TERRITORY 设置。在很多地方 1 不是星期一,而是星期日或星期六。
猜你喜欢
  • 1970-01-01
  • 2017-04-22
  • 2020-07-19
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 1970-01-01
  • 2011-12-13
相关资源
最近更新 更多