ORA-01791: 不是 SELECTed 表示式(distinct使用注意點)
not a Selected expression:不是一個查詢表示式;
原始報錯sql:
select distinct report.fid as "reportId", -- assign.fassigntype as "type", report.fsalestatus as "saleStatus", report.ftransactionstatus as "transactionStatus", report.fsettleaccountstatus as "settleAccountStatus", report.ftenementdetail as "tenementDetail", person.fid as "personId", person.fname as "personName", -- 上數業績,分成比例 (select sum(assign.fprice) || '| ' || sum(assign.fproportion) from t_trade_commissionassign assign where report.fid = assign.fktransactionreportid and assign.fkpersonid = person.fid ) as "ppsum", to_char(report.ftransactiondate,'yyyy-MM-dd') as "transactionDate" from t_hr_person person left join t_trade_commissionassign assign on person.fid=assign.fkpersonid left join t_trade_transactionreport report on assign.fktransactionreportid=report.fid where 1=1 and person.fid = '90481a8d-0c05-4002-9532-26e0482a96af' and to_char(report.ftransactiondate,'yyyy-MM-dd') >= '2017-10-24' order by report.ftransactiondate desc;
通常ORA-01791--的錯誤,都是在使用distinct後出現的。
通常是因為distinct和order by 一起使用,因為欄位名稱衝突報錯。
上面的SQL報錯是因為order by後使用的欄位名稱,使用的是原始名稱,不是使用別名“transactionDate”所導致的。
也就是說,如果有distinct時,order by後面跟的欄位名稱,必須是最新的別名(若沒有別名,就使用原來的名稱,若有多層子查詢,則使用最新的那個別名);
上面錯誤修改:
order by report.ftransactiondate desc;
改為
這樣就可以執行成功了。order by "transactionDate" desc;
distinct使用注意點:
1.必須放在查詢欄位最前面 (若不出最前面,會報錯:表示式缺失)
2.distinct後面有多個查詢欄位時,當這多個欄位完全不同時,才算是重複記錄,予以剔除
如果查詢多個欄位,只想給第一個欄位去重,那麼這樣做事不可以的
3.distinct與order by連用時,order by後面的排序欄位名,必須是最新的欄位名稱或別名。
Oracle 9i資料庫,執行下面語句出現錯誤“ORA-01791: 不是 SELECTed 表示式”:select distinct t.name from auth_employee t order by t.auth_employee_id asc
原來:SELECT語句中含有DISTINCT關鍵字或者有運算子時,排序用欄位必須與SELECT語句中的欄位相對應。
網上搜到解釋如下:在ORDER BY中指定多個列,結果將先按照子句中的第一列排序,然後第二個,依此類推。
在SELECT中未出現的列名也可用於ORDER BY 子句中,只要TABLE中有就行。但如果SELECT子句中出現了DISTINCT關鍵字,則只能用出現過的列名,而且如果SELECT子句中使用了任何運算子,在ORDER BY 子句中必須保持和SELECT子句中表達式完全一致,否則出現錯誤:“ORA-01791: 不是 SELECTed 表示式”。