将 Union All 与多个子查询结合使用,总计 return
Using Union All with Multiple Sub Queries to return Total
我有一个查询可以提取当天的各种每日统计数据。
这是我的查询:
SELECT e.Location_Name AS Location, c.customers AS Customers, '$' + CONVERT(nvarchar, CAST(c.net_sales AS money), 1) AS Sales, '$' + CONVERT(nvarchar,
CAST(e.Ticket_Goal AS Decimal(10, 2))) AS [TKT Goal], '$' + CONVERT(nvarchar, c.Ticket_avg) AS TKT, CAST(d.Labor_Hours / c.customers AS Decimal(10, 2))
AS Labor, CONVERT(nvarchar, CAST(d.Labor_Dollars / c.net_sales * 100 AS Decimal(10, 1))) + '%' AS [%]
FROM (SELECT Store_Number, SUM(Net_Sales) AS net_sales, SUM(Customers ) AS Customers , CAST(SUM(Net_Sales) / SUM(Customers ) AS decimal(10, 2))
AS Ticket_avg
FROM daily_sales_tb AS a
WHERE (Operations_Day = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0))
GROUP BY Store_Number) AS c INNER JOIN
(SELECT Store_Number, SUM(Labor_Hours) + SUM(Overtime_Labor_Hours) AS Labor_Hours, SUM(Labor_Dollars) + SUM(Overtime_Labor_Dollars)
AS Labor_Dollars
FROM daily_labor_tb AS b
WHERE (Operations_Day = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0))
GROUP BY Store_Number) AS d ON c.Store_Number = d.Store_Number INNER JOIN
(SELECT Store_Number, Ticket_Goal, Location_Name
FROM dds.Location_Table_Info_Tb) AS e ON c.Store_Number = e.Store_Number
这是输出:
Location Customers Sales TKT Goal TKT Labor %
1 100 00 .00 1.2 20%
2 200 00 .00 .50 1.3 15%
3 300 00 .00 .67 1.4 20%
4 100 0 .00 1.1 20%
这是我希望输出的样子(添加总行):
Location Customers Sales TKT Goal TKT Labor %
1 100 ,000 .00 1.2 20%
2 200 ,500 .00 .50 1.3 15%
3 300 ,000 .00 .67 1.4 20%
4 100 0 .00 1.1 20%
TOTAL: 900 ,300 - .89 - -
我尝试使用 Union All -
SELECT e.Location_Name AS Location, c.customers AS Customers, '$' + CONVERT(nvarchar, CAST(c.net_sales AS money), 1) AS Sales, '$' + CONVERT(nvarchar,
CAST(e.Ticket_Goal AS Decimal(10, 2))) AS [TKT Goal], '$' + CONVERT(nvarchar, c.Ticket_avg) AS TKT, CAST(d.Labor_Hours / c.customersAS Decimal(10, 2))
AS Labor, CONVERT(nvarchar, CAST(d.Labor_Dollars / c.net_sales * 100 AS Decimal(10, 1))) + '%' AS [%]
FROM (SELECT Store_Number, SUM(Net_Sales) AS net_sales, SUM(Customers ) AS Customers , CAST(SUM(Net_Sales) / SUM(Customers ) AS decimal(10, 2))
AS Ticket_avg
FROM daily_sales_tb AS a
WHERE (Operations_Day = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0))
GROUP BY Store_Number) AS c INNER JOIN
(SELECT Store_Number, SUM(Labor_Hours) + SUM(Overtime_Labor_Hours) AS Labor_Hours, SUM(Labor_Dollars) + SUM(Overtime_Labor_Dollars)
AS Labor_Dollars
FROM daily_labor_tb AS b
WHERE (Operations_Day = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0))
GROUP BY Store_Number) AS d ON c.Store_Number = d.Store_Number INNER JOIN
(SELECT Store_Number, Ticket_Goal, Location_Name
FROM dds.Location_Table_Info_Tb) AS e ON c.Store_Number = e.Store_Number
UNION ALL
select 'TOTAL:', SUM(Customers ), '$' + Convert(nvarchar,Cast(SUM (net_sales) as money),1), '-', Convert(nvarchar,CAST(SUM(Net_Sales) / SUM(Customers ) AS money)), '-', convert(nvarchar,'-')
from daily_sales_tb
当我 运行 这个查询时,我得到一个 SQL 错误:
Msg 8115, Level 16, State 6, Line 1
Arithmetic overflow error converting varchar to data type numeric.
如何解决这个问题才能正确输出数据?
我 运行 在 vb.net 中执行此查询,填充数据集,然后将数据集转换为 HTML table。转换完成后,我将 table 作为电子邮件正文通过电子邮件发送。
问题是查询试图将文本 'TOTAL:' 转换为数字。它这样做是为了匹配先前在该列中具有 'Store_Number' 的查询。要修复,请尝试将 'Store_Number' 转换为字符类型:
改变这个:
SELECT Store_Number
为此:
SELECT Convert(nvarchar,Store_Number) as Store_Number,
由于您没有提到列的确切数据类型,解决方案只是检查这 2 件事,它应该可以解决错误:
UNION ALL 之前的列类型应该与 UNION ALL 之后的列类型匹配。这意味着如果列的类型为 Varchar,则 UNION ALL 语句前后应存在相同的 Varchar 类型。
您可能需要检查 table 的原始列类型、您在查询中使用的转换类型和 "make sure the field is actually convertible to the type you are trying to convert"(例如:'TOTAL: can如果第一列(位置)是文本字段,则添加到 UNION ALL 中,但如果它是整数字段,则会抛出错误) - 需要对所有列进行类似的检查
注意:发生错误是因为您试图将文本字段转换为十进制,而原始字段中没有兼容的十进制值
您的第一个 select 中有 CAST(d.Labor_Hours / c.customers AS DECIMAL(10,2)) AS Labor
,您的 Union 中有 '-'
。只需将 Labor
转换为 NVARCHAR,就像您是主要 select
我有一个查询可以提取当天的各种每日统计数据。
这是我的查询:
SELECT e.Location_Name AS Location, c.customers AS Customers, '$' + CONVERT(nvarchar, CAST(c.net_sales AS money), 1) AS Sales, '$' + CONVERT(nvarchar,
CAST(e.Ticket_Goal AS Decimal(10, 2))) AS [TKT Goal], '$' + CONVERT(nvarchar, c.Ticket_avg) AS TKT, CAST(d.Labor_Hours / c.customers AS Decimal(10, 2))
AS Labor, CONVERT(nvarchar, CAST(d.Labor_Dollars / c.net_sales * 100 AS Decimal(10, 1))) + '%' AS [%]
FROM (SELECT Store_Number, SUM(Net_Sales) AS net_sales, SUM(Customers ) AS Customers , CAST(SUM(Net_Sales) / SUM(Customers ) AS decimal(10, 2))
AS Ticket_avg
FROM daily_sales_tb AS a
WHERE (Operations_Day = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0))
GROUP BY Store_Number) AS c INNER JOIN
(SELECT Store_Number, SUM(Labor_Hours) + SUM(Overtime_Labor_Hours) AS Labor_Hours, SUM(Labor_Dollars) + SUM(Overtime_Labor_Dollars)
AS Labor_Dollars
FROM daily_labor_tb AS b
WHERE (Operations_Day = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0))
GROUP BY Store_Number) AS d ON c.Store_Number = d.Store_Number INNER JOIN
(SELECT Store_Number, Ticket_Goal, Location_Name
FROM dds.Location_Table_Info_Tb) AS e ON c.Store_Number = e.Store_Number
这是输出:
Location Customers Sales TKT Goal TKT Labor %
1 100 00 .00 1.2 20%
2 200 00 .00 .50 1.3 15%
3 300 00 .00 .67 1.4 20%
4 100 0 .00 1.1 20%
这是我希望输出的样子(添加总行):
Location Customers Sales TKT Goal TKT Labor %
1 100 ,000 .00 1.2 20%
2 200 ,500 .00 .50 1.3 15%
3 300 ,000 .00 .67 1.4 20%
4 100 0 .00 1.1 20%
TOTAL: 900 ,300 - .89 - -
我尝试使用 Union All -
SELECT e.Location_Name AS Location, c.customers AS Customers, '$' + CONVERT(nvarchar, CAST(c.net_sales AS money), 1) AS Sales, '$' + CONVERT(nvarchar,
CAST(e.Ticket_Goal AS Decimal(10, 2))) AS [TKT Goal], '$' + CONVERT(nvarchar, c.Ticket_avg) AS TKT, CAST(d.Labor_Hours / c.customersAS Decimal(10, 2))
AS Labor, CONVERT(nvarchar, CAST(d.Labor_Dollars / c.net_sales * 100 AS Decimal(10, 1))) + '%' AS [%]
FROM (SELECT Store_Number, SUM(Net_Sales) AS net_sales, SUM(Customers ) AS Customers , CAST(SUM(Net_Sales) / SUM(Customers ) AS decimal(10, 2))
AS Ticket_avg
FROM daily_sales_tb AS a
WHERE (Operations_Day = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0))
GROUP BY Store_Number) AS c INNER JOIN
(SELECT Store_Number, SUM(Labor_Hours) + SUM(Overtime_Labor_Hours) AS Labor_Hours, SUM(Labor_Dollars) + SUM(Overtime_Labor_Dollars)
AS Labor_Dollars
FROM daily_labor_tb AS b
WHERE (Operations_Day = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0))
GROUP BY Store_Number) AS d ON c.Store_Number = d.Store_Number INNER JOIN
(SELECT Store_Number, Ticket_Goal, Location_Name
FROM dds.Location_Table_Info_Tb) AS e ON c.Store_Number = e.Store_Number
UNION ALL
select 'TOTAL:', SUM(Customers ), '$' + Convert(nvarchar,Cast(SUM (net_sales) as money),1), '-', Convert(nvarchar,CAST(SUM(Net_Sales) / SUM(Customers ) AS money)), '-', convert(nvarchar,'-')
from daily_sales_tb
当我 运行 这个查询时,我得到一个 SQL 错误:
Msg 8115, Level 16, State 6, Line 1
Arithmetic overflow error converting varchar to data type numeric.
如何解决这个问题才能正确输出数据?
我 运行 在 vb.net 中执行此查询,填充数据集,然后将数据集转换为 HTML table。转换完成后,我将 table 作为电子邮件正文通过电子邮件发送。
问题是查询试图将文本 'TOTAL:' 转换为数字。它这样做是为了匹配先前在该列中具有 'Store_Number' 的查询。要修复,请尝试将 'Store_Number' 转换为字符类型:
改变这个:
SELECT Store_Number
为此:
SELECT Convert(nvarchar,Store_Number) as Store_Number,
由于您没有提到列的确切数据类型,解决方案只是检查这 2 件事,它应该可以解决错误:
UNION ALL 之前的列类型应该与 UNION ALL 之后的列类型匹配。这意味着如果列的类型为 Varchar,则 UNION ALL 语句前后应存在相同的 Varchar 类型。
您可能需要检查 table 的原始列类型、您在查询中使用的转换类型和 "make sure the field is actually convertible to the type you are trying to convert"(例如:'TOTAL: can如果第一列(位置)是文本字段,则添加到 UNION ALL 中,但如果它是整数字段,则会抛出错误) - 需要对所有列进行类似的检查
注意:发生错误是因为您试图将文本字段转换为十进制,而原始字段中没有兼容的十进制值
您的第一个 select 中有 CAST(d.Labor_Hours / c.customers AS DECIMAL(10,2)) AS Labor
,您的 Union 中有 '-'
。只需将 Labor
转换为 NVARCHAR,就像您是主要 select