2014-12-07 31 views
1

總之,當我做下面的SQL命令:如何選擇某一年後,2012年新的PostgreSQL

SELECT EXTRACT(YEAR FROM pub_date) AS year FROM news_stories 

我得到的年的大名單,從2008 - 2014年。

但如果我這樣做

SELECT EXTRACT(YEAR FROM pub_date) AS year FROM news_stories WHERE year > 2010 

我得到一個空的結果。我究竟做錯了什麼?

回答

1

試試這個。在where子句中不能使用alias name。在SELECT clause(*)之前處理WHERE clause。既然你有列名爲Year你沒有得到一個錯誤。

SELECT EXTRACT(YEAR FROM pub_date) AS year 
FROM news_stories 
WHERE EXTRACT(YEAR FROM pub_date) > 2010 
+0

謝謝。我認爲AS的主要目的之一是能夠縮短一些SQL語句,比如我寫的。 – 2014-12-07 03:18:50

+0

@DanGoodspeed ALIASES可用於爲列或表創建**臨時**名稱。如果你想在'where子句'中使用別名,那麼檢查Gordan答案。 – 2014-12-07 03:58:41

1

你必須有一個名爲year在數據庫列,因爲否則SQL將返回一個錯誤。 YOu不能在定義它的selectwhere子句中使用別名。

要麼使用子查詢或重複的表達:

SELECT EXTRACT(YEAR FROM pub_date) AS year 
FROM news_stories 
WHERE EXTRACT(YEAR FROM pub_date) > 2010; 

或者爲子查詢:

select * 
from (SELECT EXTRACT(YEAR FROM pub_date) AS year 
     FROM news_stories 
    ) n 
where year > 2010; 
3

輸出列是ORDER BYGROUP BY子句中可見,因爲這些都之後施加評估SELECT子句中的表達式。他們是不可見WHEREHAVING條款。因此,您不能參考輸出列名稱year。您將不得不重複基於輸入列的表達式。顯然,有一個同名的輸入列,否則你會得到一個異常。詳細信息:

您所查詢的是快速,你倒是應該使用sargable斷言:

SELECT EXTRACT(YEAR FROM pub_date) AS year 
FROM news_stories 
WHERE pub_date >= '2010-1-1'::date; 

這通常更快,因爲Postgres的可比較直接將pub_date中的值設置爲給定值,而不從每行中提取年份冷杉噸。
更重要的是,pub_date上的普通索引可以用這種方式 - 如果Postgres希望該路由更快(僅索引掃描或足夠選擇)。

+0

因此我從那裏得到的tl; dr是「WHERE pub_date> ='2010-1-1':: date」比「WHERE EXTRACT(YEAR FROM pub_date)> 2010」更快?我只做了一些AB速度測試,並沒有發現任何變化(腳本需要3-5秒才能運行),但如果你說最好採用可調方法,那我就很好。 :-) 謝謝! – 2014-12-08 06:27:39

+0

@DanGoodspeed:當您選擇表格的一小部分或者pg可以使用僅索引掃描([example](http:// stackoverflow))時,您會發現與'pub_date'上的索引有很大區別。 COM /問題/ 24244026 /優化,GroupWise的最大值查詢/ 24377356#24377356))。當必須讀取大部分表格時,pg將使用順序掃描,您幾乎不會看到區別。無論哪種方式,3-5秒似乎*非常*長。你的桌子很大嗎?你如何衡量?你的pg版本是什麼?我會使用'EXPLAIN ANALYZE'來測試。您不希望在測試中包含網絡開銷。 – 2014-12-08 06:41:38

+0

這是一個非常不科學的測試。這是一個perl腳本,通過網絡執行一些數據庫調用(這是其中之一),並且我只是對頁面加載進行計時。 – 2014-12-08 07:37:31