2011-02-02 83 views
1

我目前使用下面的查询来获取2010年6月完成了所有检查中查询的限制日期:如何正确处理

select inspections.name 
from inspections 
where 
    to_char(inspections.insp_date, 'YYYY') = 2010 and 
    to_char(inspections.insp_date, 'MM') = 06; 

但这种感觉有点别扭。难道没有更好的方法来做到这一点?看着http://infolab.stanford.edu/~ullman/fcdb/oracle/or-time.html它似乎并不如此。如果它有所作为,我正在使用Oracle。

由于

回答

3
select inspections.name 
from inspections 
where 
    extract(year from inspections.insp_date) = 2010 and 
    extract(month from inspections.insp_date) = 6; 
+0

看起来不错。但它看起来像某种子查询。它有效吗?谢谢! – 2011-02-02 16:15:18

+0

没有子查询,只是针对简单函数的oracle特有的语法。 – 2011-02-02 16:22:23

+2

EXTRACT()不是特定于Oracle的;它是标准的SQL。 – 2011-02-02 18:00:14

11

我喜欢使用范围比较时可能的,因为这可以通过优化可用于索引扫描:

select inspections.name 
    from inspections 
where inspections.date >= DATE '2010-06-01' 
    and inspections.date < DATE '2010-07-01' 
3

另一种选择是

SELECT inspections.name 
    FROM inspections 
WHERE TRUNC(inspections.insp_date, 'MM') = date '2010-06-01'; 

从效率角度来看

  • Vincent的溶液可以潜在地使用范围扫描的索引上INSP_DATE(假设表具有数据的许多个月,使得索引访问将是最有效的计划)。
  • 我的查询可以潜在地使用基于函数的索引上TRUNC(insp_date,“MM”)再次假设表中有数据的许多个月。如果在行不同月份的数量大的变化,优化器的基数估计值可能会略有更准确,这基于函数的索引比他们将在一条直线INSP_DATE指数但这是极不可能是查询重要这很简单。它可以发挥作用,但是,如果你开始在其他地方嵌套这个查询。但是,如果您需要将INSP_DATE索引为其他原因,则维护两个不同的索引可能会浪费时间和空间。
  • 您最初的查询和利的查询可能都潜在地使用复合函数索引(虽然你会希望有一个明确的TO_NUMBER或比较字符串而不是数字,以避免隐式转换)。然而,综合指数可能是维持效率最低的(尽管我们在此讨论的是相对较小的差异),并且我认为这是指数替代品的最小干净。
4

我同意文森特的答案,但为了完整,你可以简化你到:

select inspections.name 
from inspections 
where 
    to_char(inspections.insp_date, 'YYYYMM') = '201006'; 

这甚至可以用一个指数,该指数提供了:

create index x on inspections (to_char(insp_date, 'YYYYMM'));