1. 程式人生 > >針對sql錯誤:“除非另外還指定了 TOP 或 FOR XML,否則,ORDER BY 子句在檢視、行內函數、派生表、子查詢和公用表表達式中無效”的原理與解決

針對sql錯誤:“除非另外還指定了 TOP 或 FOR XML,否則,ORDER BY 子句在檢視、行內函數、派生表、子查詢和公用表表達式中無效”的原理與解決

執行sql語句:
select * from (
select * from tab where ID>20 order by userID desc
) as a order by date desc

邏輯上看著挺對 但是報錯:
除非另外還指定了 TOP 或 FOR XML,否則,ORDER BY 子句在檢視、行內函數、派生表、子查詢和公用表表達式中無效。

解決方案:只要我們在巢狀子查詢視圖裡面加入: top 100 percent 即可
select * from (
select top 100 percent * from tab where ID>20 order by userID desc
) as a order by date desc

其中top 100 percent 的意思是:返回符合條件的100%的記錄,即所有符合條件的記錄*

原理:ORDER BY子句的查詢不能用作表的表示式,其中表的表示式包括:檢視、內聯表值函式、子查詢、派生表和共用表示式。select+order by在檢視、子查詢中的返回值不是表,而且是遊標,所以會報錯。

example:
(8)SELECT (9)DISTINCT (11)< Top Num> < select list>
(1)FROM [left_table]
(3) JOIN < right_table>
(2)ON < join_condition>
(4)WHERE < where_condition>
(5)GROUP BY
(6)WITH < CUBE | RollUP>
(7)HAVING < having_condition>
(10)ORDER BY < order_by_list>

邏輯查詢處理階段簡介
(1)FROM:對FROM子句中的前兩個表執行笛卡爾積(Cartesian product)(交叉聯接),生成虛擬表VT1
(2)ON:對VT1應用ON篩選器。只有那些使< join_condition>為真的行才被插入VT2。
(3)OUTER(JOIN):如 果指定了OUTER JOIN(相對於CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部聯接把左表標記為保留表,右外部聯接把右表標記為保留表,完全外部聯接把兩個表都標記為保留表)中未找到匹配的行將作為外部行新增到 VT2,生成VT3.如果FROM子句包含兩個以上的表,則對上一個聯接生成的結果表和下一個表重複執行步驟1到步驟3,直到處理完所有的表為止。
(4)WHERE:對VT3應用WHERE篩選器。只有使< where_condition>為true的行才被插入VT4.
(5)GROUP BY:按GROUP BY子句中的列列表對VT4中的行分組,生成VT5.
CUBE|ROLLUP:把超組(Suppergroups)插入VT5,生成VT6.
(6)HAVING:對VT6應用HAVING篩選器。只有使< having_condition>為true的組才會被插入VT7.
(7)SELECT:處理SELECT列表,產生VT8.
(8)DISTINCT:將重複的行從VT8中移除,產生VT9.
(9)ORDER BY:將VT9中的行按ORDER BY 子句中的列列表排序,生成遊標(VC10).


(10)TOP:從VC10的開始處選擇指定數量或比例的行,生成表VT11,並返回呼叫者

注:步驟10,按ORDER BY子句中的列列表排序上步返回的行,返回遊標VC10.這一步是第一步也是唯一一步可以使用SELECT列表中的列別名的步驟。這一步不同於其它步驟的 是,它不返回有效的表,而是返回一個遊標。SQL是基於集合理論的。集合不會預先對它的行排序,它只是成員的邏輯集合,成員的順序無關緊要。對錶進行排序 的查詢可以返回一個物件,包含按特定物理順序組織的行。ANSI把這種物件稱為遊標。理解這一步是正確理解SQL的基礎。

所以,必須要在遊標的基礎上用top按照比例的行,再生成表,才能返回。

相關推薦

針對sql錯誤除非另外指定 TOP FOR XML否則ORDER BY 子句檢視派生查詢公用表表無效”的原理解決

執行sql語句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date desc 邏輯上看著挺對 但是報錯: 除非另

sql 異常<除非另外指定 TOPOFFSET FOR XML否則ORDER BY 子句在視圖派生查詢公用表表無效。>

select sel top percent 異常 子句 cor 查詢 表達 問題:當子查詢內存在ORDER BY 字句時查詢會報錯 SQL: SELECT * FROM (   SELECT * FROM USER ORDER BY USER_CORD ) S. 解

除非另外指定 TOP FOR XML否則ORDER BY 子句在視圖派生查詢公用表表無效

condition 分組 gif 篩選器 使用 外部 如果 代碼 con   SQL 不同於與其他編程語言的最明顯特征是處理代碼的順序。在大數編程語言中,代碼按編碼順序被處理,但是在SQL語言中,第一個被處理的子句是FROM子句,盡管SELECT語句第一個出現,但是幾乎總是

sql:除非另外指定 TOP FOR XML否則ORDER BY 子句檢視派生查詢

執行sql語句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date desc 邏輯上看著挺對 但是報錯: 除非另外還指定了 TO

SQL Server溫故系列(3)SQL 查詢 & 公用表表 CTE

1、子查詢 Subqueries 1.1、單行子查詢 1.2、多行子查詢 1.3、相關子查詢 1.4、巢狀子查詢 1.5、子查詢小結及效能問題 2、公用表表達式 CTE 2.1、普通公用表表達式 2.2、遞迴公用表表達式 3、本文小結 1、子查詢 Subqueries 子查詢是一個巢狀在 SELE

含引數的巨集函式的區別

含引數的巨集與函式的區別 1、巨集替換不佔執行時間,只佔編譯時間;而函式呼叫則佔執行時間(分配單元、保留現場、值傳遞、返回),每次執行都要載入,所以執行起來比較慢一些。 2、 定義巨集的時候不要在巨集及其引數之間鍵入空格,因為巨集替換的時候會把你不經意打的空格當作巨集的一部分進去

SQL使用WITH AS提高性能-使用公用表表(CTE)簡化嵌套SQL

column 簡化 expr tor .com 獲取 另一個 rom 指定 一.WITH AS的含義 WITH AS短語,也叫做子查詢部分(subquery factoring),可以讓你做很多事情,定義一個SQL片斷,該SQL片斷會被整個SQL語句所用到。有的時候

SQL使用WITH AS提高效能-使用公用表表(CTE)簡化巢狀SQL

原文:http://wudataoge.blog.163.com/blog/static/80073886200961652022389/一.WITH AS的含義     WITH AS短語,也叫做子查詢部分(subquery factoring),可以讓你做很多事情,定義一

SQL Server2005公用表表(CTE)的遞迴呼叫

public resultset getResultSet(resultset) { if(resultset is null) { current_resultset =第一個結果集(包含省的記錄集) 將結果集的id儲存在集合中 getResu

公用表表(CTE)

運行 語句 提升 ... 特性 自身 技術分享 欄目 結構   在編寫T-SQL代碼時,往往需要臨時存儲某些結果集。前面我們已經廣泛使用和介紹了兩種臨時存儲結果集的方法:臨時表和表變量。除此之外,還可以使用公用表表達式的方法。公用表表達式(Common Table Expr

SQL Server 公用表表(CTE)實現遞迴

公用表表達式簡介: 公用表表達式 (CTE) 可以認為是在單個 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 語句的執行範圍內定義的臨時結果集。CTE 與派生表類似,具體表現在不儲存為物件,並且只在查詢期間有效。與派生表的不同之處在於,公用表表達式 (CTE) 具有一個

使用公用表表(CTE)簡化巢狀SQL 進行遞迴呼叫

    上圖顯示了一個表中的資料,這個表有三個欄位:id、node_name、parent_id。實際上,這個表中儲存了一個樹型結構,分三層:省、市、區。其中id表示當前省、市或區的id號、node_name表示名稱、parent_id表示節點的父節點的id。    現在有一個需求,要查詢出某個省下面的所有

SQL Server2005雜談(3)公用表表(CTE)的遞迴呼叫

 本文為原創,如需轉載,請註明作者和出處,謝謝! 先看如下一個資料表(t_tree):     上圖顯示了一個表中的資料,這個表有三個欄位:id、node_name、parent_id。實際上,這個表

Sql — CTE公用表表With用法總結

CTE(Common Table Expression) 公用表表達式,它是在單個語句的執行範圍內定義的臨時結果集,只在查詢期間有效。它可以自引用,也可在同一查詢中多次引用,實現了程式碼段的重複利用。 CTE最大的好處是提升T-Sql程式碼的可讀性,可以更加優雅簡潔的方

SQL Server2005雜談(2)公用表表(CTE)的遞迴呼叫

本文為原創,如需轉載,請註明作者和出處,謝謝! 上一篇:SQL Server2005雜談(1):使用公用表表達式(CTE)簡化巢狀SQL 先看如下一個資料表(t_tree):     上圖顯示了一

T-SQL查詢進階--詳解公用表表(CTE)

簡介      對於SELECT查詢語句來說,通常情況下,為了使T-SQL程式碼更加簡潔和可讀,在一個查詢中引用另外的結果集都是通過檢視而不是子查詢來進行分解的.但是,檢視是作為系統物件存在資料庫中,那對於結果集僅僅需要在儲存過程或是使用者自定義函式中使用一次的時候,

儲存過程——公用表表(CTE)

- 目錄 - [0. 背景說明](#0-背景說明) - [1. 定義及語法細節](#1-定義及語法細節) - [1.1 基本定義](#11-基本定義) - [1.2 基本語法](#12-基本語法) - [1.3 多個CTE同時宣告](#13-多個cte同時宣告) - [

C++(inline)巨集定義

為什麼要使用行內函數呢? 當我們定義完一個函式之後,實際呼叫的時候,函式體本身會壓入堆疊,主函式再從堆疊裡面把這部分內容提取出來,產生一定的系統開銷,對於大型函式來說,這部分開銷可能相對於函式體本身執行的開銷來說微乎其微。但是如果一個函式僅僅只是為了完成一個特別簡單的功能,

個人C++速成筆記(1) -- C++C不一樣的地方預設引數函式過載函式模板庫函式的呼叫

之前學過C,現在想稍微學習下C++,由於上班,只能利用平時的空閒時間學習,記錄一下學習歷程,激勵自己有始有終,部落格內容主要記錄C與C++不同的地方。                    

在c++普通函式 的區別

我們都知道編譯的最終產品是可執行程式——— 由一組由機器語言指令組成,在執行程式時,作業系統將這些指令載入到計算機記憶體中。因此,每一組指令都有一個特定的記憶體地址。 一.普通函式的呼叫 a.當代碼執