SQL:查找两个不同列之间差异的微创方法

时间:2016-10-19 15:57:49

标签: mysql sql-server

我专门针对SQL Server,但如果MySQL也存在,这些信息会很有用。我已经找到了如何创建一个计算两个连续行的列之间差异的列,但我感兴趣的是如何计算两个明显可识别行中一列之间的差异吗

我知道一种方法,但它需要深层查询嵌套并重复相同的基本查询。假设我有一个连接多个表的大型查询,最终归结为:

SELECT
    projectStatus AS [Project Status],
    COUNT(projectStatus) AS [# of Projects]
FROM
    projectList
GROUP BY projectStatus

让我们说它给出了以下结果:

Project Status | # of Projects
------------------------------
Delayed        |           167
Delayed Known  |            83
On Time        |            92
Ahead          |            86

我想要做的是追加一行来计算Delayed和Delayed Known行的#ofjects值之间的差异,然后省略Delayed行,如下所示:

Project Status | # of Projects
------------------------------
Delayed        |           167
Delayed Known  |            83
On Time        |            92
Ahead          |            86
Delayed Unknown|            84

基于第一个查询,我弄清楚如何执行此操作的方式如下:

SELECT
    projectStatus AS [Project Status],
    COUNT(projectStatus) AS [# of Projects]
FROM
    projectList
GROUP BY projectStatus
UNION
SELECT
    'Delayed Unknown' AS [Project Status],
    SUM([Sum Val]) AS [# of Projects]
FROM (
    SELECT
        [# of Projects] *
        CASE
            WHEN [Project Status] = 'Delayed' THEN 1
            WHEN [Project Status] = 'Delayed Known'] THEN -1
            ELSE 0
        END AS [Sum Val]
    FROM (
        SELECT
            projectStatus AS [Project Status],
            COUNT(projectStatus) AS [# of Projects]
        FROM
            projectList
        WHERE 
            projectStatus IN ('Delayed', 'Delayed Known')
        GROUP BY projectStatus
    ) AS queryC
) AS queryB

请记住这个帖子简化了基于此内部查询,但它实际上是一个由自己的UNION组成的更大的查询。因此,这很快变得丑陋并且接近难以维护的状态。

此查询的目标是充当SQL Server Reporting Services的数据集,因此我的约束是在一个查询中执行 all (除非可以在SSRS数据集中使用临时表) )。那么,在一个查询中,是否有一种侵入性较小的方法来进行此计算?

1 个答案:

答案 0 :(得分:1)

请尝试这个,可能你正在寻找类似下面的东西。

;with cte as(
    select Projectstatus, count(*) as [# of Projects]
    from @Table 
    where projectStatus IN ('Delayed', 'Delayed Known')
    group by ProjectStatus
), cte2 as(
    select 
        (Select [# of Projects] From cte Where Projectstatus = 'Delayed')
        -(Select [# of Projects] From cte Where Projectstatus = 'Delayed Known')  as DelayedUnKownProjects
)
    select Projectstatus, [# of Projects] 
    From cte
    UNION ALL 
    SELECT 'Delayed UnKnown' as Projectstatus, DelayedUnKownProjects as [# of Projects]
    From cte2