Oracle查詢錯誤分析:ORA-01791:不是SELECTed表示式

風靈使發表於2019-04-06

表結構如下:

create table HH_BOOK_GOOD  
    (  
      ID        VARCHAR2(32) not null,  
      BOOKID    VARCHAR2(32) not null,  
      GOODID    VARCHAR2(32) not null,  
      GOODPRICE FLOAT not null,  
      GOODNAME  VARCHAR2(256) not null,  
      GOODNOTE  VARCHAR2(1024) not null  
    )  

使用下面語句進行查詢

select distinct ID,BOOKID,GOODPRICE from HH_BOOK_GOOD order by GOODID;  
報ORA-01791:不是SELECTed表示式

原因是order by後面的GOODID欄位不在select查詢結果欄位之中,因為使用了distinct關鍵字。

解決方法

1、將此欄位加入到select之後

select distinct ID,BOOKID,GOODPRICE,GOODID from hh_book_good order by GOODID;  

2、如果覺得GOODID欄位是多餘的,實在是不想將它查詢出來,可修改為如下:

select ID,BOOKID,GOODPRICE  
    from(select distinct ID,BOOKID,GOODPRICE,GOODID from HH_BOOK_GOOD)  
    order by GOODID;  

ORA-01791: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後出現的。

通常是因為distinctorder by 一起使用,因為欄位名稱衝突報錯。

上面的SQL報錯是因為order by後使用的欄位名稱,使用的是原始名稱report.ftransactiondate,不是使用別名“transactionDate”所導致的。

也就是說,如果有distinct時,order by後面跟的欄位名稱,必須是最新的別名(若沒有別名,就使用原來的名稱,若有多層子查詢,則使用最新的那個別名);

上面錯誤修改:

order by report.ftransactiondate desc;

改為

order by "transactionDate" desc;

這樣就可以執行成功了。

distinct使用注意點:

1.必須放在查詢欄位最前面 (若不出最前面,會報錯:表示式缺失)

2.distinct後面有多個查詢欄位時,當這多個欄位完全不同時,才算是重複記錄,予以剔除

如果查詢多個欄位,只想給第一個欄位去重,那麼這樣做是不可以的

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

相關文章