使用Union All with Multiple Sub Queries返回Total

时间:2016-02-22 16:32:00

标签: sql sql-server vb.net sql-server-2008 dataset

我有一个查询,可以提取当天的各种日常统计信息。

这是我的问题:

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        $1000      $9.00     $10     1.2  20%
2                 200        $1500      $9.00     $7.50   1.3  15%
3                 300        $2000      $9.00     $6.67   1.4  20%
4                 100        $800       $9.00     $8      1.1  20%

以下是我想要输出的内容(添加总计):

 Location            Customers      Sales    TKT Goal   TKT   Labor   %
    1                 100        $1,000      $9.00     $10     1.2  20%
    2                 200        $1,500      $9.00     $7.50   1.3  15%
    3                 300        $2,000      $9.00     $6.67   1.4  20%
    4                 100        $800        $9.00     $8      1.1  20%
   TOTAL:             900        $5,300       -        $5.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表格。转换完成后,我会将表格通过电子邮件发送给电子邮件正文。

3 个答案:

答案 0 :(得分:1)

您的第一个选择中有CAST(d.Labor_Hours / c.customers AS DECIMAL(10,2)) AS Labor,联盟中有'-'。只需将Labor转换为NVARCHAR,就像您选择主要选项中的其余值一样

答案 1 :(得分:0)

问题是查询试图将文本'TOTAL:'转换为数字。它这样做是为了匹配在该列中具有“Store_Number”的先前查询。要解决此问题,请尝试将“Store_Number”转换为字符类型:

改变这个:

SELECT     Store_Number

To This:

SELECT     Convert(nvarchar,Store_Number) as Store_Number,

答案 2 :(得分:0)

由于您没有提到列的确切数据类型,解决方案只是检查这两件事,它应该解决错误:

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

  2. 您可能需要检查表的原始列类型,您在查询中使用的转换类型以及“确保该字段实际上可转换为您要转换的类型”(例如: 'TOTAL:如果第一列(位置)是文本字段,可以在UNION ALL中添加,但如果是整数字段,则会抛出错误) - 需要对所有列进行类似的检查

  3. 注意:发生错误是因为您尝试将文本字段转换为十进制,而原始字段中没有兼容的十进制值