使用 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
为什么这个查询有效:
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