今天工作中遇到一個問題:
執行sql “select distinct NU_TARGETID from BMS_OWN.BMS_COMMENT where CH_TYPE = 1 order by DA_CREATEDATE desc”
語句的時候 出現ORA-01791:not a SELECTed expression錯誤
因爲select distinct 和order by一起使用的時候,order by中必須是常量或者select列表中出現的表達式。
這樣會出現邏輯錯誤。
對於單表來講,如果NU_TARGETID 這個字段有unique index 並且字段有not null約束。那麼這條語句是不會出錯的。
如果是多個表join,這種情況我經過大量測試,發現仍然會出錯,所以這種特殊性目前看來只存在於單表中。使用中大家注意。
至於爲什麼會出現這種特殊性,其他的要出錯,而唯獨滿足以上紅色部分條件不錯,原因大概是這樣的:
假設NU_TARGETID 不唯一,返回時存在如下三條記錄
NU_TARGETID DA_CREATEDATE
A 2009-11-12
A 2009-11- 14
B 2009-11-13
執行distinct 後得到 A 、B (注意,這裏沒有管順序),然後根據DA_CREATEDATE 字段來確定A、B記錄的先後順序,這個時候問題就來了,order by根據哪個DA_CREATEDATE 來排序來確定AB的位置呢?如果根據第一個,那麼結果應該是AB,根據第二個結果應該是BA,確定不了了。。。。所以當然會報錯。
如果NU_TARGETID 唯一,查詢出來的記錄即使不distinct也是唯一的,這一點數據庫自己是明白的,那麼order by時,當然可以排出序來。這樣就不會出錯。
所以不管是單表還是多表,只要oracle自己區分不出根據哪個來排序就會出現這個異常.
所以現在需要用max函數來解決這個問題,跳過適用ditinct 關鍵字。直接用max函數,來滿足需求。
大意是這樣的:用order by 是要去的同一個商家的評論的最新條數。既然這樣就用max函數就行取到最新的記錄,就沒有必要用distinct了,這樣就會避免distinct 和order by 衝突
具體的sql語句如下:
select NU_TARGETID, max(DA_CREATEDATE)
from BMS_OWN.BMS_COMMENT
where CH_TYPE = 1
group by NU_TARGETID
order by max(DA_CREATEDATE) desc