使用 UNION 和 OFFSET/FETCH 的奇怪语法错误

Strange syntax error using UNION and OFFSET/FETCH

为什么这个查询有效:

WITH SELECTION_FICHE_IMMOVEIL AS 
(
SELECT
        FI.ID_FICHE_IMMOVEIL,
        FI.[ID_THEME_IMMOVEIL ] AS ID_THEME_IMMOVEIL,
        FI.ID_SOUS_THEME_IMMOVEIL,
        FI.IM_DT_CREATION,
        A.ID_ARTICLE,
        A.AR_DT_CREATION,
        CAST(A.AR_TITRE AS nvarchar(max)) as AR_TITRE,
        CAST(A.AR_ARTICLE AS nvarchar(max)) as AR_ARTICLE
    FROM ARTICLE(NOLOCK) A
        INNER JOIN FICHE_IMMOVEIL(NOLOCK) FI ON FI.ID_ARTICLE = A.ID_ARTICLE
    WHERE FI.IM_STATUT = 'LIVR' 
        AND FI.ID_USER <> 'SYS'
)
SELECT
    ID_ARTICLE,
    AR_DT_CREATION,
    AR_TITRE,
    AR_ARTICLE,
    ID_THEME_IMMOVEIL,
    ID_SOUS_THEME_IMMOVEIL
FROM SELECTION_FICHE_IMMOVEIL 
WHERE ID_THEME_IMMOVEIL = 'DC'
ORDER BY IM_DT_CREATION DESC
    OFFSET 0 ROWS
    FETCH FIRST 20000 ROWS ONLY

但是这个没有? (关键字 'union' 附近的语法不正确)

WITH SELECTION_FICHE_IMMOVEIL AS 
(
SELECT
        FI.ID_FICHE_IMMOVEIL,
        FI.[ID_THEME_IMMOVEIL ] AS ID_THEME_IMMOVEIL,
        FI.ID_SOUS_THEME_IMMOVEIL,
        FI.IM_DT_CREATION,
        A.ID_ARTICLE,
        A.AR_DT_CREATION,
        CAST(A.AR_TITRE AS nvarchar(max)) as AR_TITRE,
        CAST(A.AR_ARTICLE AS nvarchar(max)) as AR_ARTICLE
    FROM ARTICLE(NOLOCK) A
        INNER JOIN FICHE_IMMOVEIL(NOLOCK) FI ON FI.ID_ARTICLE = A.ID_ARTICLE
    WHERE FI.IM_STATUT = 'LIVR' 
        AND FI.ID_USER <> 'SYS'
)
SELECT
    ID_ARTICLE,
    AR_DT_CREATION,
    AR_TITRE,
    AR_ARTICLE,
    ID_THEME_IMMOVEIL,
    ID_SOUS_THEME_IMMOVEIL
FROM SELECTION_FICHE_IMMOVEIL 
WHERE ID_THEME_IMMOVEIL = 'DC'
ORDER BY IM_DT_CREATION DESC
    OFFSET 0 ROWS
    FETCH FIRST 20000 ROWS ONLY
UNION
SELECT
    ID_ARTICLE,
    AR_DT_CREATION,
    AR_TITRE,
    AR_ARTICLE,
    ID_THEME_IMMOVEIL,
    ID_SOUS_THEME_IMMOVEIL
FROM SELECTION_FICHE_IMMOVEIL 
WHERE ID_THEME_IMMOVEIL = 'RL'
ORDER BY IM_DT_CREATION DESC 
    OFFSET 0 ROWS
    FETCH FIRST 10000 ROWS ONLY

我会改为使用 ROW_NUMBER()

WITH SELECTION_FICHE_IMMOVEIL AS 
(
SELECT
        FI.ID_FICHE_IMMOVEIL,
        FI.[ID_THEME_IMMOVEIL ] AS ID_THEME_IMMOVEIL,
        FI.ID_SOUS_THEME_IMMOVEIL,
        FI.IM_DT_CREATION,
        A.ID_ARTICLE,
        A.AR_DT_CREATION,
        CAST(A.AR_TITRE AS nvarchar(max)) as AR_TITRE,
        CAST(A.AR_ARTICLE AS nvarchar(max)) as AR_ARTICLE,

        ROW_NUMBER() OVER (PARTITION BY FI.[ID_THEME_IMMOVEIL ]
                           ORDER BY FI.IM_DT_CREATION) as rn

    FROM ARTICLE(NOLOCK) A
        INNER JOIN FICHE_IMMOVEIL(NOLOCK) FI ON FI.ID_ARTICLE = A.ID_ARTICLE
    WHERE FI.IM_STATUT = 'LIVR' 
        AND FI.ID_USER <> 'SYS'
)
SELECT
    ID_ARTICLE,
    AR_DT_CREATION,
    AR_TITRE,
    AR_ARTICLE,
    ID_THEME_IMMOVEIL,
    ID_SOUS_THEME_IMMOVEIL
FROM SELECTION_FICHE_IMMOVEIL 
WHERE
   (ID_THEME_IMMOVEIL = 'DC' AND rn <= 20000) OR
   (ID_THEME_IMMOVEIL = 'RL' and rn <= 10000)
ORDER BY IM_DT_CREATION DESC

您在 UNION 两边都有 ORDER BY 子句可能有点不高兴 - 通常,您需要指定一个涵盖整个组合结果集的 ORDER .

或者,您可以通过将各个查询作为子查询括起来来保留您的 UNION

您的错误是由于在您的 UNION 中有针对特定查询的 ORDER BY 子句。根据 this MSDN page:

Using UNION of two SELECT statements with ORDER BY

The order of certain parameters used with the UNION clause is important. The following example shows the incorrect and correct use of UNION in two SELECT statements in which a column is to be renamed in the output.

-- Uses AdventureWorks  

IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL  
DROP TABLE dbo.Gloves;  
GO  
-- Create Gloves table.  
SELECT ProductModelID, Name  
INTO dbo.Gloves  
FROM Production.ProductModel  
WHERE ProductModelID IN (3, 4);  
GO  

/* INCORRECT */  
-- Uses AdventureWorks  

SELECT ProductModelID, Name  
FROM Production.ProductModel  
WHERE ProductModelID NOT IN (3, 4)  
ORDER BY Name  
UNION  
SELECT ProductModelID, Name  
FROM dbo.Gloves;  
GO  

/* CORRECT */  
-- Uses AdventureWorks  

SELECT ProductModelID, Name  
FROM Production.ProductModel  
WHERE ProductModelID NOT IN (3, 4)  
UNION  
SELECT ProductModelID, Name  
FROM dbo.Gloves  
ORDER BY Name;  
GO