You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含UNION的SQL查询/存储过程总行数统计(COUNT(*)报错)

解决含UNION的SQL查询总行数统计问题

我来帮你搞定这个统计问题!你遇到的报错大概率是因为原查询里包含了ORDER BY子句——当把带ORDER BY的查询作为子查询套在COUNT(*)外面时,SQL Server不允许未加TOP/OFFSET的子查询带有排序(因为子查询返回的是集合,排序对集合本身没有意义)。下面给你几种可行的解决方法:

方法一:直接统计总行数(最简方案)

把你的整个查询去掉最后的order by ProjectID desc作为子查询,外层用COUNT(*)统计即可:

SELECT COUNT(*) AS TotalRows
FROM (
    SELECT ProjectName, ProjectReference, ProjectID, SiteSupervisor, PrincipalContractor, PrincipalDesigner 
    FROM CompanyProjects 
    WHERE EndDate < GETDATE() 
    UNION 
    (
        SELECT CompanyProjects.ProjectName AS ProjectName, CompanyProjects.ProjectReference AS ProjectReference, 
               CompanyProjects.ProjectID AS ProjectID, CompanyProjects.SiteSupervisor AS SiteSupervisor, 
               CompanyProjects.PrincipalContractor AS PrincipalContractor, CompanyProjects.PrincipalDesigner AS PrincipalDesigner 
        FROM CompanyProjects 
        INNER JOIN CompanyCurrentReview ON companyprojects.ProjectID = CompanyCurrentReview.ReviewProjectId 
            AND CompanyCurrentReview.IsReviewComplete = 0 
            AND CompanyCurrentReview.DateTime BETWEEN DATEADD(YEAR, -2, GETDATE()) AND GETDATE() 
            AND ProjectID NOT IN (SELECT ProjectID FROM CompanyProjects WHERE EndDate < GETDATE())
    ) 
    UNION 
    (
        SELECT ProjectName, ProjectReference, ProjectID, SiteSupervisor, PrincipalContractor, PrincipalDesigner 
        FROM CompanyProjects 
        WHERE CreatedDate BETWEEN DATEADD(YEAR, -2, GETDATE()) AND GETDATE() 
            AND ProjectID NOT IN (
                (SELECT CompanyProjects.ProjectID 
                 FROM CompanyProjects 
                 INNER JOIN CompanyCurrentReview ON companyprojects.ProjectID = CompanyCurrentReview.ReviewProjectId 
                     AND CompanyCurrentReview.IsReviewComplete = 0 
                     AND CompanyCurrentReview.DateTime between DateAdd(year,-2,GETDATE() ) AND GETDATE()) 
                UNION 
                SELECT ProjectID FROM CompanyProjects WHERE EndDate < GETDATE()
            )
    )
) AS result;

方法二:同时返回结果和总行数

如果你既要拿到原查询的排序结果,又要知道总行数,可以用COUNT(*) OVER()窗口函数,这样每一行数据都会附带总行数:

SELECT *, COUNT(*) OVER() AS TotalRows
FROM (
    SELECT ProjectName, ProjectReference, ProjectID, SiteSupervisor, PrincipalContractor, PrincipalDesigner 
    FROM CompanyProjects 
    WHERE EndDate < GETDATE() 
    UNION 
    (
        SELECT CompanyProjects.ProjectName AS ProjectName, CompanyProjects.ProjectReference AS ProjectReference, 
               CompanyProjects.ProjectID AS ProjectID, CompanyProjects.SiteSupervisor AS SiteSupervisor, 
               CompanyProjects.PrincipalContractor AS PrincipalContractor, CompanyProjects.PrincipalDesigner AS PrincipalDesigner 
        FROM CompanyProjects 
        INNER JOIN CompanyCurrentReview ON companyprojects.ProjectID = CompanyCurrentReview.ReviewProjectId 
            AND CompanyCurrentReview.IsReviewComplete = 0 
            AND CompanyCurrentReview.DateTime BETWEEN DATEADD(YEAR, -2, GETDATE()) AND GETDATE() 
            AND ProjectID NOT IN (SELECT ProjectID FROM CompanyProjects WHERE EndDate < GETDATE())
    ) 
    UNION 
    (
        SELECT ProjectName, ProjectReference, ProjectID, SiteSupervisor, PrincipalContractor, PrincipalDesigner 
        FROM CompanyProjects 
        WHERE CreatedDate BETWEEN DATEADD(YEAR, -2, GETDATE()) AND GETDATE() 
            AND ProjectID NOT IN (
                (SELECT CompanyProjects.ProjectID 
                 FROM CompanyProjects 
                 INNER JOIN CompanyCurrentReview ON companyprojects.ProjectID = CompanyCurrentReview.ReviewProjectId 
                     AND CompanyCurrentReview.IsReviewComplete = 0 
                     AND CompanyCurrentReview.DateTime between DateAdd(year,-2,GETDATE() ) AND GETDATE()) 
                UNION 
                SELECT ProjectID FROM CompanyProjects WHERE EndDate < GETDATE()
            )
    )
) AS result 
ORDER BY ProjectID desc;

针对含UNION的存储过程的统计方法

如果是存储过程里的UNION逻辑需要统计行数,你可以用这两种方式:

  • 方式一:临时表中转统计
    先把存储过程的结果插入临时表,再对临时表执行COUNT:

    CREATE TABLE #TempResults (
        ProjectName VARCHAR(255),
        ProjectReference VARCHAR(255),
        ProjectID INT,
        SiteSupervisor VARCHAR(255),
        PrincipalContractor VARCHAR(255),
        PrincipalDesigner VARCHAR(255)
    );
    
    INSERT INTO #TempResults
    EXEC YourStoredProcedureName; -- 替换成你的存储过程名
    
    SELECT COUNT(*) AS TotalRows FROM #TempResults;
    
    DROP TABLE #TempResults;
    
  • 方式二:修改存储过程返回统计数
    在存储过程里先统计行数,再返回原结果,比如:

    CREATE PROCEDURE YourStoredProcedureName
    AS
    BEGIN
        -- 先返回总行数
        SELECT COUNT(*) AS TotalRows
        FROM (
            -- 这里放入你的UNION查询内容(去掉ORDER BY)
        ) AS result;
    
        -- 再返回原查询的排序结果
        SELECT ProjectName, ProjectReference, ProjectID, SiteSupervisor, PrincipalContractor, PrincipalDesigner 
        FROM (
            -- 这里放入你的UNION查询内容
        ) AS result 
        ORDER BY ProjectID desc;
    END
    

内容的提问来源于stack exchange,提问作者assaduzzaman samrat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:07:59