【发布时间】:2013-05-15 12:13:41
【问题描述】:
我正在尝试针对我们数据库中的一组运输条目生成一份报告(每月、年初至今等),以显示正确的总和并按运输公司对其进行分组。我怎样才能完成获取所有这些信息并生成正确的报告?
需要注意的一点是,该表中的所有条目都是 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 打印每月总运费的过滤列表。下线我想得到一份年初至今的清单和类似的东西。无论如何,我希望看到的月度报告是这样的:
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 子句中的任何表达式都不匹配”,这是有道理的。我真的很想了解背后的理论,不仅是为什么第二个示例不起作用,而且是什么正确的行动方案才能使转换起作用。
【问题讨论】:
-
我不知道为什么你的第二个例子没有工作...... :P 因为它在这里工作sqlfiddle.com/#!6/197c9/14你在第二个查询中收到什么错误??
-
@Meherzad - 当我执行“示例 2”的查询时,我得到“将数据类型 nvarchar 转换为数字时出错”。当我执行“示例 3”时,我得到“分组函数的参数 1 与 GROUP BY 子句中的任何表达式都不匹配。”
标签: sql sql-server tsql sql-server-2012