问大家个聚合函数求和的问题。分不多。诚心受教!

阿桐 2011-03-18 03:08:11
比如说我要连表查一个表中一列值的总和

select COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCategoryid
left join tblType t on fc.typeid=t.Typeid
left join _Community co on co.CommunityId=c.CommunityId
--where (CommunityID='+@Communityid+' or '+@Communityid+' is null)
group by co.CommunityName
order by '合计' desc

查出来的数据如下:

合计
1 105
2 81
3 76
4 57
5 56
6 56
7 55
8 47
9 35
10 31

现在我要想计算 合计 一列的总和 。再怎么写SQL语句计算。希望大家帮帮忙。谢谢了。
...全文
442 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
大Y 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 luoyoumou 的回复:]
SQL code
-- 不需要再用嵌套查询,把group by 去掉,就是楼主要的结果了嘛!

select COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCate……
[/Quote]

上面的都是高手呀,一个比一个强.
不是太懂,觉的, 17 楼说的就对!
阿桐 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 luoyoumou 的回复:]
引用 23 楼 sytlkx 的回复:

引用 20 楼 luoyoumou 的回复:
SQL code
-- 如果cid是表tblCase中的字段的话,
-- 这样一看,所有的 left join 都是多余的,
-- 直接:
select count(cid) from
tblCase;


我要查的是连表之后的统计再求和。
不是这一个表的。这样数据就多了啊。


……
[/Quote]
恩恩,我搞错了。呵呵。#20 #22 可取。这就结贴了。谢谢大家。
-晴天 2011-03-18
  • 打赏
  • 举报
回复
如果这样的话,就把总计写在同一个数据列中了:
;with c1 as(
select top 100 COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCategoryid
left join tblType t on fc.typeid=t.Typeid
left join _Community co on co.CommunityId=c.CommunityId
--where (CommunityID='+@Communityid+' or '+@Communityid+' is null)
group by co.CommunityName
order by '合计' desc
)
select * from c1
union all
select sum(合计) from c1
AcHerat 元老 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 sytlkx 的回复:]

引用 20 楼 luoyoumou 的回复:
SQL code
-- 如果cid是表tblCase中的字段的话,
-- 这样一看,所有的 left join 都是多余的,
-- 直接:
select count(cid) from
tblCase;


我要查的是连表之后的统计再求和。
不是这一个表的。这样数据就多了啊。
[/Quote]

子查询的排序是没有意义的,再说你是最后统计它们的和,还计较排序做什么。
快溜 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 sytlkx 的回复:]
order by 无效那怎么写。。。。愁~
[/Quote]
order by 不等于group by,你搞反了吧,order不影响结果
luoyoumou 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 sytlkx 的回复:]

引用 20 楼 luoyoumou 的回复:
SQL code
-- 如果cid是表tblCase中的字段的话,
-- 这样一看,所有的 left join 都是多余的,
-- 直接:
select count(cid) from
tblCase;


我要查的是连表之后的统计再求和。
不是这一个表的。这样数据就多了啊。
[/Quote]

-- 你执行过吗?真的多了吗?你了解left join 和 right join 的原理吗?
-晴天 2011-03-18
  • 打赏
  • 举报
回复
你既然要求总计,那这儿的order by 就没有意义了,可以不写:


select sum(合计) as 总计 from(
select COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCategoryid
left join tblType t on fc.typeid=t.Typeid
left join _Community co on co.CommunityId=c.CommunityId
--where (CommunityID='+@Communityid+' or '+@Communityid+' is null)
group by co.CommunityName
)t

如果你一定要写,那加个top 100:

select sum(合计)as 总计 from(
select top 100 COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCategoryid
left join tblType t on fc.typeid=t.Typeid
left join _Community co on co.CommunityId=c.CommunityId
--where (CommunityID='+@Communityid+' or '+@Communityid+' is null)
group by co.CommunityName
order by '合计' desc
)T
阿桐 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 luoyoumou 的回复:]
SQL code
-- 如果cid是表tblCase中的字段的话,
-- 这样一看,所有的 left join 都是多余的,
-- 直接:
select count(cid) from
tblCase;
[/Quote]

我要查的是连表之后的统计再求和。
不是这一个表的。这样数据就多了啊。
快溜 2011-03-18
  • 打赏
  • 举报
回复
select COUNT(cid) as no into #tb from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCategoryid
left join tblType t on fc.typeid=t.Typeid
left join _Community co on co.CommunityId=c.CommunityId
--where (CommunityID='+@Communityid+' or '+@Communityid+' is null)
group by co.CommunityName

select sum(no) from #tb
drop table #tb
--再错?
luoyoumou 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 sytlkx 的回复:]

引用 17 楼 luoyoumou 的回复:
SQL code
-- 不需要再用嵌套查询,把group by 去掉,就是楼主要的结果了嘛!

select COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCa……
[/Quote]

-- 为什么要这样做呢?
luoyoumou 2011-03-18
  • 打赏
  • 举报
回复
-- 如果cid是表tblCase中的字段的话,
-- 这样一看,所有的 left join 都是多余的,
-- 直接:
select count(cid) from
tblCase;
阿桐 2011-03-18
  • 打赏
  • 举报
回复
order by 无效那怎么写。。。。愁~
阿桐 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 luoyoumou 的回复:]
SQL code
-- 不需要再用嵌套查询,把group by 去掉,就是楼主要的结果了嘛!

select COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCate……
[/Quote]
我要的是这个结果的。count的再sum啊。。
luoyoumou 2011-03-18
  • 打赏
  • 举报
回复
-- 不需要再用嵌套查询,把group by 去掉,就是楼主要的结果了嘛!

select COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCategoryid
left join tblType t on fc.typeid=t.Typeid
left join _Community co on co.CommunityId=c.CommunityId
--where (CommunityID='+@Communityid+' or '+@Communityid+' is null);
luoyoumou 2011-03-18
  • 打赏
  • 举报
回复
-- 在 SQL Server里,子查询不能用Order by
阿桐 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 acherat 的回复:]
引用 2 楼 abcjun188 的回复:

SQL code
select sum(合计) as total from
(
select COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid……
[/Quote]
order by我写了,不行。还是那个错。
Msg 1033, Level 15, State 1, Line 11
除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效。
阿桐 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 luoyoumou 的回复:]
SQL code
-- 查出来的数据,为什么有两个字段?
查出来的数据如下:

合计
1 105
2 81
3 76
4 57
5 56
6 56
7 55
8 47
9 35
10 31

-- 你的SQL语句中,select 只有 一个字段啊,还有一个字段是哪儿来的?
[/Quote]

序号啊。早知道这能迷惑你们,就不写了。
luoyoumou 2011-03-18
  • 打赏
  • 举报
回复
-- 查出来的数据,为什么有两个字段?
查出来的数据如下:

合计
1 105
2 81
3 76
4 57
5 56
6 56
7 55
8 47
9 35
10 31

-- 你的SQL语句中,select 只有 一个字段啊,还有一个字段是哪儿来的?
AcHerat 元老 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 abcjun188 的回复:]

SQL code
select sum(合计) as total from
(
select COUNT(cid) as '合计' from tblCase c
left join tblFlow f on c.Flowid=f.Flowid
left join tblFlowCategory fc on f.FlowCategoryid =fc.FlowCategoryid
l……
[/Quote]

2# 的子查询里没有 order by ,楼主你没复制对,重新复制2#的看。
luoyoumou 2011-03-18
  • 打赏
  • 举报
回复
-- 2008
SELECT
i.Shelf,
i.LocationID,
p.Name,
SUM(i.Quantity) Total
FROM Production.ProductInventory i
INNER JOIN Production.Product p ON
i.ProductID = p.ProductID
WHERE Shelf IN ('A','C') AND
Name IN ('Chain', 'Decal', 'Head Tube')
GROUP BY GROUPING SETS
((i.Shelf), (i.Shelf, p.Name), (i.LocationID, p.Name));

-- 1.11.4 展现 GROUPING 生成的行 ( P44 )
-- 你可能会注意到,在前面的技巧中,进行分组的那些行在没有参与聚合总和的列中有 NULL 值。例如,当为货架C生成总和时,地区产品名称列为 NULL:

-- 如果数据中确定不包含 NULL,那么 NULL 值是可接受的;但是,如果存在 NULL 值呢?如何区分出那些“存储的” NULL 和
-- 由 ROLLUP、CUBE 和 GROUPING SETS 生成的 NULL 呢?

-- 为了确定这个问题,可以使用 GROUPING_ID。在SQL Server的早期版本中,GROUPING是可用的,它可以简单地评估一行是否为聚合的产物。例如,
-- 下面的查询使用 CASE 语句来评估行是否为根据货架统计的总和、根据地区统计的总和、全部合计或是通常的非 cube 的行:
SELECT
i.Shelf,
i.LocationID,
CASE
WHEN GROUPING(i.Shelf) = 0 AND
GROUPING(i.LocationID) = 1 THEN 'Shelf Total'
WHEN GROUPING(i.Shelf) = 1 AND
GROUPING(i.LocationID) = 0 THEN 'Location Total'
WHEN GROUPING(i.Shelf) = 1 AND
GROUPING(i.LocationID) = 1 THEN 'Grand Total'
ELSE 'Regular Row'
END RowType,
SUM(i.Quantity) Total
FROM Production.ProductInventory i
WHERE LocationID = 2
GROUP BY CUBE (i.Shelf,i.LocationID)

-- 解析
-- GROUPING 函数允许你区分并操作那些使用 CUBE、ROLLUP 和 GROUPING SETS聚合自动生成的行。在这个示例中,先用平常的SELECT语句,
-- 该语句包含了Shelf和Location列:
SELECT
i.Shelf,
i.LocationID,

-- 在这之后,是一个CASE语句,用来计算GROUPING 语句的返回值并合并。

-- 如果 GROUPING 返回的值为1(真),表示NULL不是实际的数据值,而是聚合操作的结果,可以理解为值“全部”。因此在示例中,如果由于CUBE聚合过程而不是数据本身,
-- 造成货架的值不为NULL但地区ID为NULL,则返回字符串Shelf Total:

......

-- 1.11.5 使用 GROUPING_ID 标识分组级别
-- 随着增加到 GROUP BY 的新列和可分组与聚合的唯一数据值,标识出哪些行属于哪一种聚合变得更加困难。
-- 例如,假设我有一个非聚合报表,显示了地区为3和箱柜为1和2的产品数量:
SELECT
i.Shelf,
i.LocationID,
i.Bin,
i.Quantity
FROM Production.ProductInventory i
WHERE i.LocationID IN (3) AND
i.Bin IN (1,2)

-- 现在如果希望生成基于货架、地区和箱柜的各种组合的聚合报表,可以使用 CUBE 产生所有这些潜在组合的汇总:
SELECT
i.Shelf,
i.LocationID,
i.Bin,
SUM(i.Quantity) Total
FROM Production.ProductInventory i
WHERE i.LocationID IN (3) AND
i.Bin IN (1,2)
GROUP BY CUBE (i.Shelf,i.LocationID,i.Bin)
ORDER BY i.Shelf, i.LocationID, i.Bin

-- 尽管查询返回了CUBE期望的各种聚合,但结果仍然是难以理解的:

-- 这时GROUPING_ID就派上用场了。使用这个函数,可以确定行的分组级别。这个函数比GROUPING更加复杂,这是因为GROUPING_ID用一个或多个列作为输入,
-- 然后返回列的二进制数字计算结果对应的整数。

-- 这可以通过示例进行最好的描述,因此我将使用前面的查询,并增加CASE逻辑来返回合适的行描述符:
SELECT
i.Shelf,
i.LocationID,
i.Bin,
CASE GROUPING_ID(i.Shelf,i.LocationID,i.Bin)
WHEN 1 THEN 'Shelf/Location Total'
WHEN 2 THEN 'Shelf/Bin Total'
WHEN 3 THEN 'Shelf Total'
WHEN 4 THEN 'Location/Bin Total'
WHEN 5 THEN 'Location Total'
WHEN 6 THEN 'Bin Total'
WHEN 7 THEN 'Grand Total'
ELSE 'Regular Row'
END,
SUM(i.Quantity) Total
FROM Production.ProductInventory i
WHERE i.LocationID IN (3) AND
i.Bin IN (1,2)
GROUP BY CUBE (i.Shelf,i.LocationID,i.Bin)
ORDER BY i.Shelf, i.LocationID, i.Bin

Self Loc Bin
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

......

-- 1.12 公共表达式 ( P49 )
-- 公共表达式 (CTE) 和视图或衍生查询相似,允许创建一个临时的查询,该查询能在SELECT、INSERT、UPDATE或DELETE查询范围中引用。
-- 和衍生查询不同,不需要在每次使用CTE的时候复制查询定义多次。同时也能在CTE定义中使用局部变量----这是在视图定义中所不能做到的。

CTE 的基本语法如下:

WITH expression_name [ ( column_name [,...n] ) ]
AS ( CTE_query_definition )

-- 表1-4描述了CTE的参数。

---------------------------------------------------------------------------------
| 表1-4 CTE 参数 |
---------------------------------------------------------------------------------
| 参 数 | 描 述 |
---------------------------------------------------------------------------------
| expression_name | 公共表达式的名字 |
---------------------------------------------------------------------------------
| column_name [,...n] | 表达式的唯一列名 |
---------------------------------------------------------------------------------
| CTE_query_definition | 定义公共表达式的SELECT查询 |
---------------------------------------------------------------------------------

-- 非递归的CTE在查询中不引用自己。它就像查询的临时结果集。递归的CTE的定义和非递归的CTE差不多,只是递归的CTE返回层次化的以及和自身相关的数据。
-- 和其他方式相比,使用CTE来表示递归数据能尽量减少需要的代码量。

-- 接下来的两个技巧会演示非递归的和递归的CTE。

-- 1.12.1 使用非递归的公共表表达式 ( P49 )
-- 这个公共表达式的示例演示返回Purchasing.Vendor表中的供应商----返回根据名字排序的前5个和最后5个结果:
WITH VendorSearch (RowNumber, VendorName, AccountNumber)
AS
(
SELECT ROW_NUMBER() OVER (ORDER BY Name) RowNum,
Name,
AccountNumber
FROM Purchasing.Vendor
)

SELECT RowNumber,
VendorName,
AccountNumber
FROM VendorSearch
WHERE RowNumber BETWEEN 1 AND 5
UNION
SELECT RowNumber,
VendorName,
AccountNumber
FROM VendorSearch
WHERE RowNumber BETWEEN 100 AND 104

-- 前面的示例使用了UNION,但是非递归的CTE也能像其他SELECT查询那样使用:
WITH VendorSearch (VendorID,VendorName)
AS
(
SELECT VendorID,
Name
FROM Purchasing.Vendor
)

SELECT v.VendorID,
v.VendorName,
p.ProductID,
p.StandardPrice
FROM VendorSearch v
INNER JOIN Purchasing.ProductVendor p ON
v.VendorID = p.VendorID
ORDER BY v.VendorName

-- 警告 如果CTE是一批语句的一部分,那么CTE定义之前的语句必须以分号结尾。

-- 注意 可以使用分号作为 SQL Server 语句的终止符。多数情况下这样做不是必需的,但是符合ANSI标准,你可以在一些微软的文件中看到这样的使用。

-- 1.12.2 使用递归的公共表达式 ( P52 )
-- 在这个示例中,新的Company 表定义了一个假想的巨大的联合企业。每一个公司都有一个CompanyID和可选的ParentCompanyID。
-- 这个示例会演示如何使用递归CTE在结果中显示公司的层次。首先,创建表:
CREATE TABLE dbo.Company
(CompanyID int NOT NULL PRIMARY KEY,
ParentCompanyID int NULL,
CompanyName varchar(25) NOT NULL)

-- 接着,向新表中插入行(使用SQL Server 2008新语法的方式将在第2章中演示):
INSERT dbo.Company (CompanyID, ParentCompanyID, CompanyName)
VALUES
(1,NULL,'Mega-Corp'),
(2,1,'Mediamus-Corp'),
(3,1,'KindaBigus-Corp'),
(4,3,'GettinSmaller-Corp'),
(5,4,'Smallest-Corp'),
(6,5,'Puny-Corp'),
(7,5,'Small2-Corp')

-- 现在就是实际例子:
WITH CompanyTree(ParentCompanyID,CompanyID,CompanyName,CompanyLevel)
AS
(
SELECT ParentCompanyID,
CompanyID,
CompanyName,
0 AS CompanyLevel
FROM dbo.Company
WHERE ParentCompanyID IS NULL
UNION ALL
SELECT c.ParentCompanyID,
c.CompanyID,
c.CompanyName,
p.CompanyLevel + 1
FROM dbo.Company c
INNER JOIN CompanyTree p
ON c.ParentCompanyID = p.CompanyID
)
SELECT ParentCompanyID, CompanyID, CompanyName, CompanyLevel
FROM CompanyTree

......

-- 然而,使用这种有用的新特性需要小心。如果你没有正确地创建递归CTE,可能会产生无限循环。
-- 在测试的时候,要避免无限循环,可以使用本章前面提到的MAXRECURSION提示。

-- 例如,如果希望阻止前面的示例超过2级,只需要在查询最后添加具有MAXRECURSION的OPTION子句:
WITH CompanyTree(ParentCompanyID, CompanyID, CompanyName, CompanyLevel) AS
(
SELECT ParentCompanyID,CompanyID,CompanyName, 0 AS CompanyLevel
FROM dbo.Company
WHERE ParentCompanyID IS NULL
UNION ALL
SELECT c.ParentCompanyID, c.CompanyID, c.CompanyName, p.CompanyLevel + 1
FROM dbo.Company c
INNER JOIN CompanyTree p
ON c.ParentCompanyID = p.CompanyID
)
SELECT ParentCompanyID, CompanyID, CompanyName, CompanyLevel
FROM CompanyTree
OPTION (MAXRECURSION 2)
加载更多回复(10)

34,873

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧