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

时间:2016-12-15 09:06:58

标签: sql-server union fetch offset common-table-expression

为什么此查询有效:

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

2 个答案:

答案 0 :(得分:1)

我转而使用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

对于ORDER BY双方都有UNION条款,您可能有点不高兴 - 通常,您需要指定一个覆盖整个组合的ORDERUNION结果集。

或者,您可以通过将各个查询作为子查询括起来保留{{1}}。

答案 1 :(得分:1)

您的错误是由于UNION中针对特定查询的-- 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 条款造成的。根据{{​​3}}:

  

使用带有ORDER BY的两个SELECT语句的UNION

     

与UNION子句一起使用的某些参数的顺序是   重要。以下示例显示了错误和正确的用法   UNION在两个SELECT语句中,其中要重命名一列   在输出中。

var gulp = require('gulp');
var uglify = require('gulp-uglify'); //uglifies your JavaScript
var minify = require('gulp-htmlmin'); //minifies your HTML

gulp.task('build', ['uglify', 'copyHTML'], function() {});

gulp.task('copyHTML', function() {
    return gulp.src('client/**/*.html')
        .pipe(minify({ collapseWhitespace: true })
        .pipe(gulp.dest('dist/'));
});

gulp.task('uglify', function() {
    return gulp.src('client/**/*.js')
        .pipe(uglify())
        .pipe(gulp.dest('dist/'));
});