首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Server:如何在SELECT语句中的不同列上使用2+聚合函数?

Server:如何在SELECT语句中的不同列上使用2+聚合函数?
EN

Stack Overflow用户
提问于 2017-03-15 21:55:51
回答 4查看 311关注 0票数 0

我正在Server 2012中工作。我有以下简单的表格:

代码语言:javascript
运行
复制
CREATE TABLE t
(
    NK1 varchar(255)
    ,NK2 varchar(255)
    ,ID int
    ,amount decimal(10,2)
);

INSERT INTO t
    SELECT 'a', 'x', 3, 10.00 UNION ALL
    SELECT 'a', 'x', 1, 5.00 UNION ALL
    SELECT 'a', 'x', 0, 15.00 UNION ALL
    SELECT 'a', 'y', 1, 0.00 UNION ALL
    SELECT 'a', 'y', 10, -5.00 UNION ALL
    SELECT 'b', 'x', 2, 10.00 UNION ALL
    SELECT 'b', 'y', 0, 0.00 UNION ALL
    SELECT 'b', 'y', -1, 15.00 UNION ALL
    SELECT 'b', 'y', 3, 10.00 UNION ALL
    SELECT 'b', 'y', 15, 10.00;

NK1NK2定义表的自然键。我的目标是返回最大行号(对于每个自然键:ORDER BY NK1 ASC, NK2 ASC, ID ASC)、对应的amount值以及每个自然键的amount列之和。

因此,对于给定的表,我期望得到以下结果集:

代码语言:javascript
运行
复制
NK1 || NK2 || max_RowNumber || amount || sum_amount
a   | x    | 1              | 10.00   | 30.00
a   | y    | 2              | -5.00   | -5.00
b   | x    | 1              | 10.00   | 10.00
b   | y    | 4              | 10.00   | 35.00

我在单个2+语句中使用SELECT聚合函数(显然,在2+不同的列上)有问题。

以下是我的尝试:

代码语言:javascript
运行
复制
WITH cte AS
(
    SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY NK1, NK2 ORDER BY NK1, NK2, ID) AS RowNumber
    FROM
        t
)
SELECT
    NK1, NK2,
    MAX(RowNumber) AS max_RowNumber,
    amount,
    SUM(amount) AS sum_amount
FROM
    cte
GROUP BY
    NK1, NK2;

当我运行上面的查询时,我会得到以下错误:

关键字“From”附近的语法不正确。

它指的是"FROM cte“这句话。我认为这是因为2+聚合函数在SELECT中的不同列上。

特别是,"SUM“一行说

‘'SUM’不是一个公认的内置函数名。

我该怎么解决这个问题?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-03-15 22:05:41

该错误是由最终的SELECT语句包含amount造成的,但是amount不在您的GROUP BY中。

如果将amount从最后的查询中删除,(而不是SUM(amount) ),它可以正常工作。

代码语言:javascript
运行
复制
WITH cte AS (
SELECT *
    ,ROW_NUMBER() OVER (
      PARTITION BY
        NK1
        ,NK2
      ORDER BY
        NK1
        ,NK2
        ,ID
      ) AS RowNumber
FROM
  t
)
SELECT
   NK1
   ,NK2
   ,MAX(RowNumber) AS max_RowNumber
   ,SUM(amount) AS sum_amount
FROM cte
GROUP BY
NK1
,NK2;

结果:

代码语言:javascript
运行
复制
NK1  NK2  max_RowNumber  sum_amount
---- ---- -------------- ----------
a    x    3              30.00
b    x    1              10.00
a    y    2              -5.00
b    y    4              35.00
票数 0
EN

Stack Overflow用户

发布于 2017-03-15 22:00:55

我有一个不同的错误:

列'cte.amount‘在select列表中无效,因为它既不包含在聚合函数中,也不包含在GROUP BY子句中。

从查询中删除,amount时,它工作得很好:

代码语言:javascript
运行
复制
;

WITH cte AS
(
SELECT
  *
  ,ROW_NUMBER() OVER (
                     PARTITION BY
                       NK1
                       ,NK2
                     ORDER BY
                       NK1
                       ,NK2
                       ,ID
                     ) AS RowNumber
  FROM
      t
)
SELECT
   NK1
   ,NK2
   ,MAX(RowNumber) AS max_RowNumber
   ,SUM(amount) AS sum_amount
FROM
   cte
GROUP BY
   NK1
   ,NK2
;

结果:

代码语言:javascript
运行
复制
NK1     NK2     max_RowNumber   sum_amount
a       x       3               30,00
b       x       1               10,00
a       y       2               -5,00
b       y       4               35,00

在rextester中自己看看

票数 2
EN

Stack Overflow用户

发布于 2017-03-15 22:16:22

我已经推翻了Zohar的答案,因为他首先清除了错误,但是我想知道为什么您要这样使用row_number()

代码语言:javascript
运行
复制
with cte as (
 select *
  , row_number() over (
      partition by NK1, NK2 
      order by  NK1, NK2,ID /* NK1, NK2 don't do anything here either */
   ) as RowNumber
 from t
 )
select 
     NK1
   , NK2
   , max(RowNumber) as max_RowNumber
   , sum(amount) as sum_amount
from cte
group by NK1, NK2;

怎么会跟这个不一样?

代码语言:javascript
运行
复制
select 
     NK1
   , NK2
   , count(*) as max_RowNumber
   , sum(amount) as sum_amount
from t
group by NK1, NK2;

rextester演示展示相同的结果:http://rextester.com/XSGIP25353

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42821434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档