gpt4 book ai didi

sql - 每月报告的 TSQL Sum by group

转载 作者:行者123 更新时间:2023-12-04 04:58:25 26 4
gpt4 key购买 nike

我正在尝试针对我们数据库中的一组运输条目生成一份报告(每月、年初至今等),以显示正确的总金额并按运输公司对它们进行分组。我怎样才能完成获取所有这些信息并生成正确的报告?

需要注意的一件事是,由于使用来自各种来源的奇数字符导入文本,该表中的所有条目都是 nvarchar(max)。

主数据库列表如下所示:

表-shipping_info

shipping_company | ship_date | shipping_category | shipping_cost

UPS | 20130301 | CD'S | 3.50
UPS | 20130310 | Records | 4.50
UPS | 20130322 | CD'S | 7.50
UPS | 20130313 | Tapes | 12.44
UPS | 20130324 | CD'S | 3.50
UPS | 20120312 | Records | 4.50
UPS | 20120304 | CD'S | 5.50
UPS | 20120306 | Tapes | 3.50
UPS | 20130309 | CD'S | 3.50
USPS | 20130301 | Tapes | 3.50
USPS | 20130301 | CD'S | 5.50
USPS | 20130301 | CD'S | 4.50
USPS | 20130201 | Tapes | 3.50
USPS | 20130201 | CD'S | 3.50
USPS | 20130201 | Records | 7.50
USPS | 20130201 | Tapes | 9.50
USPS | 20130201 | CD'S | 12.50
USPS | 20120301 | CD'S | 14.50
USPS | 20120301 | Records | 3.50
USPS | 20130301 | CD'S | 23.50
USPS | 20120301 | Tapes | 15.50
USPS | 20120301 | CD'S | 34.50
DHL | 20120301 | Tapes | 35.50
DHL | 20120301 | CD'S | 3.50
DHL | 20130301 | Tapes | 3.50
DHL | 20130401 | CD'S | 3.50
DHL | 20130401 | Records | 4.50
DHL | 20130501 | CD'S | 4.50
DHL | 20120201 | Tapes | 5.50
DHL | 20120101 | CD'S | 6.50
DHL | 20120501 | CD'S | 3.50
DHL | 20120301 | Tapes | 7.50

我的目标是获得一个最终列表,该列表将按 Shipping_company 打印每月总运费的过滤列表。接下来,我想得到一份迄今为止的 list 和类似的东西。无论如何,我希望月度报告发生的事情是这样的:
UPS Shipping Cost Report for March 2013

CD's - $23.50
Records - $9.00
Tapes - $15.94

我首先尝试的是
SELECT shipping_company, ship_date, shipping_category, shipping_cost FROM shipping_info WHERE (shipping_company = 'UPS' and shipping_cost IS NOT NULL and shipping_cost != '')  GROUP BY shipping_company, ship_date, shipping_category, shipping_cost ORDER BY shipping_company, ship_date, shipping_category, shipping_cost 

这产生了一个很好的过滤表,但我仍然需要计算出总和并按类别将总数分组在一起。

然后我尝试了这个......
SELECT shipping_company, ship_date, shipping_category, SUM(shipping_cost) FROM shipping_info WHERE (shipping_company = 'UPS' and shipping_cost IS NOT NULL and shipping_cost != '')  GROUP BY shipping_company, ship_date, shipping_category, shipping_cost ORDER BY shipping_company, ship_date, shipping_category, shipping_cost 

由于这是一个 NVARCHAR(MAX) 表,t-sql 出错了,错误告诉我我需要将 shipping_cost 转换为 int。

所以......我接下来尝试了这个。
SELECT shipping_company, ship_date, shipping_category, convert(decimal(10, 2), shipping_cost) FROM shipping_info WHERE (shipping_company = 'UPS' and shipping_cost IS NOT NULL and shipping_cost != '')  GROUP BY shipping_company, ship_date, shipping_category, shipping_cost ORDER BY shipping_company, ship_date, shipping_category, shipping_cost 

哪种有效,哪种无效。

现在,当涉及到将这个列表分解为可报告的部分时,我很难从第一个示例中的哪个方向继续进行。我是否走在正确的道路上,将我的信息转化为我需要的月度报告格式?

::编辑/更新::

这很棒,而且很有效。我花了一些时间来完成这段代码的每一步,现在我明白了这里发生的事情背后的理论。这里还有最后一件事我很纠结。由于该表是 NVARCHAR(MAX),我在尝试将 ship_date 转换为数字时遇到了挑战,但没有成功。

我采用了下面的原始代码 - 示例 1:
select  
CASE WHEN (GROUPING(shipping_company) = 1) THEN 'TOTAL'
ELSE shipping_company END AS shipping_company,
CASE WHEN (GROUPING(SUBSTRING(ship_date, 1, 6)) = 1) THEN 'TOTAL'
ELSE SUBSTRING(ship_date, 1, 6) END AS Date,
CASE WHEN (GROUPING(shipping_category) = 1) THEN 'Yearly TOTAL'
ELSE shipping_category END AS shipping_category,
sum(convert(decimal(10,2),shipping_cost))
from tbl
group by shipping_company, SUBSTRING(ship_date, 1, 6),
shipping_category WITH rollup

然后添加数字转换命令,如下所示 - 示例 2:
select  
CASE WHEN (GROUPING(shipping_company) = 1) THEN 'TOTAL'
ELSE shipping_company END AS shipping_company,
CASE WHEN (GROUPING(CONVERT(numeric, (SUBSTRING(ship_date, 1, 6))) = 1) THEN 'TOTAL'
ELSE (CONVERT(numeric, SUBSTRING(ship_date, 1, 6))) END AS Date,
CASE WHEN (GROUPING(shipping_category) = 1) THEN 'Yearly TOTAL'
ELSE shipping_category END AS shipping_category,
sum(convert(decimal(10,2),shipping_cost))
from tbl
group by shipping_company, (CONVERT(numeric, SUBSTRING(ship_date, 1, 6))),
shipping_category WITH rollup

但仍然将 nvarchar 转换为数字错误。然后我像这样移动了东西 - 示例 3:
select  
CASE WHEN (GROUPING(shipping_company) = 1) THEN 'TOTAL'
ELSE shipping_company END AS shipping_company,
CASE WHEN (CONVERT(numeric, GROUPING(SUBSTRING(ship_date, 1, 6))) = 1) THEN 'TOTAL'
ELSE (CONVERT(numeric, SUBSTRING(ship_date, 1, 6))) END AS Date,
CASE WHEN (GROUPING(shipping_category) = 1) THEN 'Yearly TOTAL'
ELSE shipping_category END AS shipping_category,
sum(convert(decimal(10,2),shipping_cost))
from tbl
group by shipping_company, (CONVERT(numeric, SUBSTRING(ship_date, 1, 6))),
shipping_category WITH rollup

并得到“分组函数的参数 1 与 GROUP BY 子句中的任何表达式都不匹配”,这是有道理的。我真的很想了解背后的理论,不仅是为什么第二个例子不起作用,而且是使转换起作用的正确行动方案是什么。

最佳答案

试试这个查询

我从日期中提取了年份和月份的部分,因此分组发生在特定年份的每个月。

select 
shipping_company,
SUBSTRING(ship_date, 1, 6),
shipping_category,
sum(convert(decimal(10,2),shipping_cost))
from
tbl
group by
shipping_company,
SUBSTRING(ship_date, 1, 6),
shipping_category

SQL FIDDLE :
| SHIPPING_COMPANY | COLUMN_1 | SHIPPING_CATEGORY | COLUMN_3 |
--------------------------------------------------------------
| DHL | 201201 | CD'S | 6.5 |
| DHL | 201202 | CD'S | 5.5 |
| DHL | 201203 | CD'S | 46.5 |
| DHL | 201205 | CD'S | 3.5 |
| DHL | 201303 | CD'S | 3.5 |
| DHL | 201304 | CD'S | 8 |
| DHL | 201305 | CD'S | 4.5 |
| UPS | 201203 | CD'S | 5.5 |
| UPS | 201203 | Records | 4.5 |
| UPS | 201203 | Tapes | 3.5 |
| UPS | 201303 | CD'S | 18 |
| UPS | 201303 | Records | 4.5 |
| UPS | 201303 | Tapes | 12.44 |
| USPS | 201203 | CD'S | 68 |
| USPS | 201302 | CD'S | 36.5 |
| USPS | 201303 | CD'S | 37 |

如果您想要年度总数,那么您可以使用 WITH ROLLUP .

注意 将年度总计视为每月总计...

查询 1 :
select  
CASE WHEN (GROUPING(shipping_company) = 1) THEN 'TOTAL'
ELSE shipping_company END AS shipping_company,
CASE WHEN (GROUPING(SUBSTRING(ship_date, 1, 6)) = 1) THEN 'TOTAL'
ELSE SUBSTRING(ship_date, 1, 6) END AS Date,
CASE WHEN (GROUPING(shipping_category) = 1) THEN 'Yearly TOTAL'
ELSE shipping_category END AS shipping_category,
sum(convert(decimal(10,2),shipping_cost))
from tbl
group by shipping_company, SUBSTRING(ship_date, 1, 6),
shipping_category WITH rollup

SQL FIDDLE :
| SHIPPING_COMPANY |   DATE | SHIPPING_CATEGORY | COLUMN_3 |
------------------------------------------------------------
| DHL | 201201 | CD'S | 6.5 |
| DHL | 201201 | Yearly TOTAL | 6.5 |
| DHL | 201202 | CD'S | 5.5 |
| DHL | 201202 | Yearly TOTAL | 5.5 |
| DHL | 201203 | CD'S | 46.5 |
| DHL | 201203 | Yearly TOTAL | 46.5 |
| DHL | 201205 | CD'S | 3.5 |
| DHL | 201205 | Yearly TOTAL | 3.5 |
| DHL | 201303 | CD'S | 3.5 |
| DHL | 201303 | Yearly TOTAL | 3.5 |
| DHL | 201304 | CD'S | 8 |
| DHL | 201304 | Yearly TOTAL | 8 |
| DHL | 201305 | CD'S | 4.5 |
| DHL | 201305 | Yearly TOTAL | 4.5 |
| DHL | TOTAL | Yearly TOTAL | 78 |
| UPS | 201203 | CD'S | 5.5 |
| UPS | 201203 | Records | 4.5 |
| UPS | 201203 | Tapes | 3.5 |
| UPS | 201203 | Yearly TOTAL | 13.5 |
| UPS | 201303 | CD'S | 18 |
| UPS | 201303 | Records | 4.5 |
| UPS | 201303 | Tapes | 12.44 |
| UPS | 201303 | Yearly TOTAL | 34.94 |
| UPS | TOTAL | Yearly TOTAL | 48.44 |
| USPS | 201203 | CD'S | 68 |
| USPS | 201203 | Yearly TOTAL | 68 |
| USPS | 201302 | CD'S | 36.5 |
| USPS | 201302 | Yearly TOTAL | 36.5 |
| USPS | 201303 | CD'S | 37 |
| USPS | 201303 | Yearly TOTAL | 37 |
| USPS | TOTAL | Yearly TOTAL | 141.5 |
| TOTAL | TOTAL | Yearly TOTAL | 267.94 |

编辑

好的,您在更新的查询中遇到了问题。 If 语句的两种情况都应返回相同的结果数据类型,因此当您尝试将日期值转换回数字时,您的真实情况将返回 varchar数据类型字段是 TOTAL并且 else 字段返回 numeric type 字段,因此这会导致错误。

要解决它,您需要删除 case 语句,然后它会根据您的需要正常工作。
select  
CASE WHEN (GROUPING(shipping_company) = 1) THEN 'TOTAL'
ELSE shipping_company END AS shipping_company,
CONVERT(numeric, (SUBSTRING(ship_date, 1, 6))) AS Date,
CASE WHEN (GROUPING(shipping_category) = 1) THEN 'Yearly TOTAL'
ELSE shipping_category END AS shipping_category,
sum(convert(decimal(10,2),shipping_cost))
from tbl
group by shipping_company, (CONVERT(numeric, SUBSTRING(ship_date, 1, 6))),
shipping_category WITH rollup

SQL FIDDLE :
| SHIPPING_COMPANY |   DATE | SHIPPING_CATEGORY | COLUMN_3 |
------------------------------------------------------------
| DHL | 201201 | CD'S | 6.5 |
| DHL | 201201 | Yearly TOTAL | 6.5 |
| DHL | 201202 | CD'S | 5.5 |
| DHL | 201202 | Yearly TOTAL | 5.5 |
| DHL | 201203 | CD'S | 46.5 |
| DHL | 201203 | Yearly TOTAL | 46.5 |
| DHL | 201205 | CD'S | 3.5 |
| DHL | 201205 | Yearly TOTAL | 3.5 |
| DHL | 201303 | CD'S | 3.5 |
| DHL | 201303 | Yearly TOTAL | 3.5 |
| DHL | 201304 | CD'S | 8 |
| DHL | 201304 | Yearly TOTAL | 8 |
| DHL | 201305 | CD'S | 4.5 |
| DHL | 201305 | Yearly TOTAL | 4.5 |
| DHL | (null) | Yearly TOTAL | 78 |
| UPS | 201203 | CD'S | 5.5 |
| UPS | 201203 | Records | 4.5 |
| UPS | 201203 | Tapes | 3.5 |
| UPS | 201203 | Yearly TOTAL | 13.5 |
| UPS | 201303 | CD'S | 18 |
| UPS | 201303 | Records | 4.5 |
| UPS | 201303 | Tapes | 12.44 |
| UPS | 201303 | Yearly TOTAL | 34.94 |
| UPS | (null) | Yearly TOTAL | 48.44 |
| USPS | 201203 | CD'S | 68 |
| USPS | 201203 | Yearly TOTAL | 68 |
| USPS | 201302 | CD'S | 36.5 |
| USPS | 201302 | Yearly TOTAL | 36.5 |
| USPS | 201303 | CD'S | 37 |
| USPS | 201303 | Yearly TOTAL | 37 |
| USPS | (null) | Yearly TOTAL | 141.5 |
| TOTAL | (null) | Yearly TOTAL | 267.94 |

所以现在你必须忍受日期列中的空值。希望这能解答你的疑惑。

希望这有帮助......

关于sql - 每月报告的 TSQL Sum by group,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16454370/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com