1. 程式人生 > >ORA-01791: 不是 SELECTed 表示式(distinct使用注意點)

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 表示式”。