2016-02-22 65 views
-1

我有一个查询可以获取当天的各种日常统计数据。使用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.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表格。转换完成后,我会将表格作为电子邮件的主体发送给我们。

+1

SQL Server是否具有ROLLUP或类似的,可以用来代替那个UNION ALL? – jarlh

+1

你真的应该在你的显示层中做大部分显示内容(无论你的前端是什么)。 –

+0

我正在使用vb。净 - 但是,我将数据集转换为HTML表格,并通过电子邮件发送出去。在中间添加它并不是一个好的选择。 – Shmewnix

回答

1

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

+0

完美!谢谢! – Shmewnix

0

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

更改此:

SELECT  Store_Number 

这样:

SELECT  Convert(nvarchar,Store_Number) as Store_Number, 
+0

你指的是主要查询“位置”中的第一个选择,或者你指的是我引用“Store_Number”的子查询我转换了“Location_Name”的初始选择,我仍然想出同样的错误。 – Shmewnix

+0

子查询。当您执行联合(或联合全部)时,所有列需要具有相同的数据类型。也就是说,所有查询的第一列需要具有相同的数据类型。所有秒都需要匹配,三分之一,等等。 –

+0

我在所有的子查询中改变了它。相同的错误 – Shmewnix

0

既然你没有提到的列的确切数据类型时,解决方案只是检查这两件事情,它应该解决这个错误:

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

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

注意:出现此错误是因为您要将文本字段转换为原始字段中没有兼容小数值的小数点

+0

原始查询运行完成。只要添加了Union All查询 - 就是当我收到错误。 – Shmewnix