SQL SUM 基于一列一表的前两个字符
Posted
技术标签:
【中文标题】SQL SUM 基于一列一表的前两个字符【英文标题】:SQL SUM based on first two characters of one column, one table 【发布时间】:2012-04-18 18:55:12 【问题描述】:我对 SQL 还很陌生,有以下两难境地。我有以下部分表:
账户描述 ShortDescription 余额 ------------------------------------------------ 100001 废话,废话,废话 28350.68 100020 " " 2537.35 111000 " " 86898.12 111001 " " 63943.63 121000 " " 55325.68 121012 " " 65264.35 122000 " " 94898.85
我需要从前两位数开始对所有帐户的余额求和。所以前两个余额相加,接下来的两个相加,接下来的三个相加,等等。然后我需要把这些和创建一个总计。
最终表将包括所有列、SubTotal 和 GrandTotal。我想不出一个好的方法来做到这一点;我尝试了 OVER - PARTITION BY 没有成功(SELECT SUM(Balance) OVER (PARTITION BY Account) AS SubTotal)。任何帮助,将不胜感激。提前致谢。
【问题讨论】:
我认为 SQL 的设计初衷不是为了处理这些要求。您最好使用一些报告系统之王来生成小计。 【参考方案1】:这是输出包含总计和小计的表格的一种方式:
-- select individual Rows
select Account, Description, ShortDescription, Balance from Accounts
union
-- subtotals
select
substring(Account, 1, 2) as Account,
substring(Account, 1, 2) + ' Subtotal' as Description,
'' as ShortDescription,
sum(Balance) as Balance
from Accounts
group by substring(Account, 1, 2)
union
-- grand total
select
'' as Account,
'Grand Total' as Description,
'' as ShortDescription,
sum(Balance) as Balance
from Accounts
-- order all records to give the illusion of interlaced subtotals/grand total
order by Account desc
但是,我认为最佳解决方案是从表中进行简单选择并使用报告工具(例如 SQL Server Reporting Services)处理总计/小计。
请注意,在上述声明中,我假设 Account
列的类型为 char
/varchar
。如果它被声明为int
或其他数字类型,您应该添加适当的转换/转换转换。 (union
中的所有数据集必须具有相同的列数和相同的数据类型)
【讨论】:
谢谢w0lf!这很好用!在现实世界中,我会使用报告工具;这就是他们的目的。但这对我来说是查询培训。我现在可以对 UNION 进行研究;我以前从未见过。再次感谢。 我很高兴这有帮助。这是UNION
的 TSQL 文档:msdn.microsoft.com/en-us/library/ms180026.aspx【参考方案2】:
我认为最初的问题是正确编写分区有点困难,因为语法有点痛苦。如果我不明白您正在寻找什么(各行中的所有值和总计)作为 w0lf 提供的简单替代方案,那么这可能是一个更快的解决方案:
Select *, SUM(Balance) OVER (PARTITION BY substring(Account, 1, 2)) as Subtotal,
Sum(Balance) over(Partition by 1) as Total
from dbo.Accounts
这给出了每个原始列 (*),以及一个小计列和一个总计列,使用分区上的总和。
我使用了以下结构和您的数据,如果您遇到任何错误,这可能会有所帮助:
CREATE TABLE dbo.Accounts (Account varchar(10), [Description] varchar(10),
ShortDescription varchar(10), Balance money) GO
INSERT INTO Accounts (Account, Description, ShortDescription, Balance) VALUES
(100001, 'Blah', 'Blah2', 28350.68),(100020, 'Blah', 'Blah2', 2537.35),
(111000, 'Blah', 'Blah2', 86898.12),(111001, 'Blah', 'Blah2', 63943.63),
(121000, 'Blah', 'Blah2', 55325.68),(121012, 'Blah', 'Blah2', 65264.35),
(122000, 'Blah', 'Blah2', 94898.85)
作为附录,如果 Accounts 存储为数字,您可以使用 substring(cast(Account as varchar(max)), 1, 2)) 代替 substring(Account, 1, 2)。
【讨论】:
谢谢大卫!我认为可能有一种方法可以使用 OVER - PARTITION BY 但它不起作用。虽然 w0lf 的格式更好,但为了简单起见,我仍坚持使用此代码。我今天学到了两件事 - UNION 和 SUBSTRING!再次感谢!以上是关于SQL SUM 基于一列一表的前两个字符的主要内容,如果未能解决你的问题,请参考以下文章