将 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 件事,它应该可以解决错误:

  1. UNION ALL 之前的列类型应该与 UNION ALL 之后的列类型匹配。这意味着如果列的类型为 Varchar,则 UNION ALL 语句前后应存在相同的 Varchar 类型。

  2. 您可能需要检查 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