2011-02-02 138 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'));