Sql 尝试使用公共表表达式对列标题的别名求和

Sql 尝试使用公共表表达式对列标题的别名求和,sql,sql-server,ssms,alias,common-table-expression,Sql,Sql Server,Ssms,Alias,Common Table Expression,我有一个数据表,其中记录了几周内的通过和失败情况 我想计算每周的尝试次数,以及通过和失败的次数,然后取这些通过和失败的总和作为检查 SELECT week, COUNT (Week) as weekcount, sum(case when result = 'pass' then 1 else 0 end) as 'passcount' , sum(case when result = 'fail' then 1 else 0 end) as 'failcount'

我有一个数据表,其中记录了几周内的通过和失败情况

我想计算每周的尝试次数,以及通过和失败的次数,然后取这些通过和失败的总和作为检查

SELECT week, 
    COUNT (Week) as weekcount, 

    sum(case when result = 'pass' then 1 else 0 end) as 'passcount' ,
    sum(case when result = 'fail' then 1 else 0 end) as 'failcount',
        sum(case when result = 'pass' then 1 else 0 end) +
        sum(case when result = 'fail' then 1 else 0 end) as 'sum'

FROM table1
group by week
order by week
上面的代码片段满足了我的要求,但我一直在阅读关于CTE的文章,将其作为在查询中重复的替代方法

我希望能够在查询中使用别名“passcount”和“failcount”,而无需将它们作为列添加到表中。我已尝试在下面首先设置CTE

with sums as
(
    select result,
    sum(case when result = 'pass' then 1 else 0 end) as 'passcount' ,
    sum(case when result = 'fail' then 1 else 0 end) as 'failcount',
    from table1 
)
上面报告了结尾括号附近的语法错误,但我无法理解原因


有谁能解释一下这一点或更好的方法吗?

在SQL Server中,我认为横向连接(即交叉应用)比子查询和CTE更干净。在您的情况下,可以在聚合之前生成标志,因此如下所示:

select week, count(*) as weekcount, 
       sum(ispass) as passcount,
       sum(isfail) as failcount,
       (sum(ispass) + sum(isfail)) as passfailcount
from table1 t1 cross apply
     (values (case when result = 'pass' then 1 else 0 end,
              case when result = 'fail' then 1 else 0 end
             )
     ) v(ispass, isfail)
group by week
order by week

在SQL Server中,我认为横向联接(即交叉应用)比子查询和CTE更干净。在您的情况下,可以在聚合之前生成标志,因此如下所示:

select week, count(*) as weekcount, 
       sum(ispass) as passcount,
       sum(isfail) as failcount,
       (sum(ispass) + sum(isfail)) as passfailcount
from table1 t1 cross apply
     (values (case when result = 'pass' then 1 else 0 end,
              case when result = 'fail' then 1 else 0 end
             )
     ) v(ispass, isfail)
group by week
order by week

你只需要在论文之后再选择一篇

with sums as
(
    select result,
    sum(case when result = 'pass' then 1 else 0 end) as 'passcount' ,
    sum(case when result = 'fail' then 1 else 0 end) as 'failcount',
    from table1 
)
select result, passcount, failcount, passcount + failcount as sum
from sums;

你只需要在论文之后再选择一篇

with sums as
(
    select result,
    sum(case when result = 'pass' then 1 else 0 end) as 'passcount' ,
    sum(case when result = 'fail' then 1 else 0 end) as 'failcount',
    from table1 
)
select result, passcount, failcount, passcount + failcount as sum
from sums;

实际上,您不需要同时编写
大小写
表达式,只需在中使用

SELECT Week,
       COUNT(Week) AS weekcount,
       COUNT(CASE Result WHEN 'pass' THEN 1 END) AS PassCount,
       COUNT(CASE Result WHEN 'fail' THEN 1 END) AS FailCount,
       COUNT(CASE WHEN Result IN ('pass','fail') THEN 1 END) AS PassFailCount
FROM Table1
GROUP BY Week
ORDER BY Week;

是的,这并没有告诉您如何使用CTE,但是,逻辑比重复两个
CASE
表达式“更清晰”(更简洁)。

您实际上不需要同时编写两个
CASE
表达式,您可以在
中使用

SELECT Week,
       COUNT(Week) AS weekcount,
       COUNT(CASE Result WHEN 'pass' THEN 1 END) AS PassCount,
       COUNT(CASE Result WHEN 'fail' THEN 1 END) AS FailCount,
       COUNT(CASE WHEN Result IN ('pass','fail') THEN 1 END) AS PassFailCount
FROM Table1
GROUP BY Week
ORDER BY Week;

是的,这并没有告诉您如何使用CTE,但是,与重复两个
大小写
表达式相比,逻辑“更清晰”(更简洁)。

我不确定您为什么要考虑CTE,您可以在一组中完成:

SELECT 
        [Week], 
        COUNT([Week]) AS weekcount
    ,   SUM(CASE WHEN result = 'pass' THEN 1 ELSE 0 END) AS passcount   
    ,   SUM(CASE WHEN result = 'fail' THEN 1 ELSE 0 END) AS failcount
    ,   COUNT(*) AS TotalSum
FROM table1
GROUP BY [Week]
在SQL Server中,您不能引用来自同一选择的别名,例如passcount、weekcount..等。这是您需要解决方法的方式,例如使用子查询、CTE、联接、交叉应用或任何其他用于此目的的方法

以下是一些常用的方法:

使用子查询

SELECT 
    [Week]
,   SUM(weekcount) weekcount
,   SUM(passcount) passcount
,   SUM(failcount) failcount
,   SUM(passcount + failcount) AS TotalSum
FROM (
    SELECT 
        [Week], 
        COUNT([Week]) AS weekcount
    ,   SUM(CASE WHEN result = 'pass' THEN 1 ELSE 0 END) AS passcount   
    ,   SUM(CASE WHEN result = 'fail' THEN 1 ELSE 0 END) AS failcount
    FROM table1
    GROUP BY [Week]
) D 
GROUP BY 
    [Week]
使用CTE方法:

;WITH CTE AS (
    SELECT 
        [Week], 
        COUNT([Week]) AS weekcount
    ,   SUM(CASE WHEN result = 'pass' THEN 1 ELSE 0 END) AS passcount   
    ,   SUM(CASE WHEN result = 'fail' THEN 1 ELSE 0 END) AS failcount
    FROM table1
    GROUP BY [Week]
)
SELECT      
        [Week]
    ,   SUM(weekcount) weekcount
    ,   SUM(passcount) passcount
    ,   SUM(failcount) failcount
    ,   SUM(passcount + failcount) AS TotalSum
FROM CTE 
GROUP BY 
    [Week]
使用交叉应用方法: 参考@Gordon Linoff答案(基本和直接)


这些是您可以在您的案例中使用的最简单的方法,您也可以在您的案例中使用PIVOT,但是为了简单起见,我没有提到它

我不知道您为什么要考虑CTE,您可以在一套中完成:

SELECT 
        [Week], 
        COUNT([Week]) AS weekcount
    ,   SUM(CASE WHEN result = 'pass' THEN 1 ELSE 0 END) AS passcount   
    ,   SUM(CASE WHEN result = 'fail' THEN 1 ELSE 0 END) AS failcount
    ,   COUNT(*) AS TotalSum
FROM table1
GROUP BY [Week]
在SQL Server中,您不能引用来自同一选择的别名,例如passcount、weekcount..等。这是您需要解决方法的方式,例如使用子查询、CTE、联接、交叉应用或任何其他用于此目的的方法

以下是一些常用的方法:

使用子查询

SELECT 
    [Week]
,   SUM(weekcount) weekcount
,   SUM(passcount) passcount
,   SUM(failcount) failcount
,   SUM(passcount + failcount) AS TotalSum
FROM (
    SELECT 
        [Week], 
        COUNT([Week]) AS weekcount
    ,   SUM(CASE WHEN result = 'pass' THEN 1 ELSE 0 END) AS passcount   
    ,   SUM(CASE WHEN result = 'fail' THEN 1 ELSE 0 END) AS failcount
    FROM table1
    GROUP BY [Week]
) D 
GROUP BY 
    [Week]
使用CTE方法:

;WITH CTE AS (
    SELECT 
        [Week], 
        COUNT([Week]) AS weekcount
    ,   SUM(CASE WHEN result = 'pass' THEN 1 ELSE 0 END) AS passcount   
    ,   SUM(CASE WHEN result = 'fail' THEN 1 ELSE 0 END) AS failcount
    FROM table1
    GROUP BY [Week]
)
SELECT      
        [Week]
    ,   SUM(weekcount) weekcount
    ,   SUM(passcount) passcount
    ,   SUM(failcount) failcount
    ,   SUM(passcount + failcount) AS TotalSum
FROM CTE 
GROUP BY 
    [Week]
使用交叉应用方法: 参考@Gordon Linoff答案(基本和直接)


这些是您可以在您的案例中使用的最简单的方法,您也可以在您的案例中使用PIVOT,但是为了简单起见,我没有提到它

当遇到错误时,如果你发布它,这真的很有帮助;否则,我们只能猜测您的查询失败的原因。至于您的CTE查询,我们似乎遗漏了一些内容。CTE声明后,您的
选择
更新
等语句在哪里?如果没有错误和完整的SQL,我们甚至不可能开始解决您的问题。您得到的错误是由于您的cte中缺少group by子句。我要注意的是,您的CTE只是一个完整查询的一个片段,它本身无法执行。我还将指出,您可以使用简单的case形式(例如,case result when'fail'then…)而不是搜索形式(例如,case when result='fail'then…)。小心这些建议。若结果可以有“通过”和“失败”以外的值,则需要调整它们以正确处理。在你的QA过程中一定要测试它。当遇到错误时,如果你发布它,它会非常有帮助;否则,我们只能猜测您的查询失败的原因。至于您的CTE查询,我们似乎遗漏了一些内容。CTE声明后,您的
选择
更新
等语句在哪里?如果没有错误和完整的SQL,我们甚至不可能开始解决您的问题。您得到的错误是由于您的cte中缺少group by子句。我要注意的是,您的CTE只是一个完整查询的一个片段,它本身无法执行。我还将指出,您可以使用简单的case形式(例如,case result when'fail'then…)而不是搜索形式(例如,case when result='fail'then…)。小心这些建议。若结果可以有“通过”和“失败”以外的值,则需要调整它们以正确处理。确保在你的QA过程中测试这一点。我如何将周数纳入其中?我以为它会是括号后面的select函数的一部分?我应该在初始CTE中包含它吗?每次尝试对此进行更改时,我都会收到一个错误:列“table1.result”在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。这是来自第一个选择,但我不知道如何修复它。我如何将周数合并到其中?我以为它会是括号后面的select函数的一部分?我应该在初始CTE中包含它吗?每次尝试对此进行更改时,我都会收到一个错误:列“table1.result”在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。这是从第一个选择,但我不知道何