在子查询的SQL Server中使用减号

时间:2018-06-21 13:45:08

标签: sql sql-server tsql

我正在学习sql server,如果我问愚蠢的问题,请在这里重新使用。我的问题是

找出2007年11月和12月之间的总销售额差异

这是我的查询->

select novsales,decsales 
FROM (
    SELECT saleskey,sum(salesamount) as novsales 
    FROM FactSales 
    WHERE month(DateKey) = 11 
    AND YEAR(DateKey) =2007 
) as a 
INNER join (
    SELECT saleskey,sum(SalesAmount) as decsales 
    FROM FactSales 
    WHERE month(DateKey) = 12 
    AND YEAR(DateKey) =2007
) as b on a.SalesKey = b.SalesKey

3 个答案:

答案 0 :(得分:1)

虽然查询是正确的,但是您应该使用FULL JOIN,因为对于销售键来说,左侧或右侧可能没有行

select a.saleskey,
novsales=ISNULL(novsales,0),
decsales =ISNULL(decsales ,0),
salesdiff=ISNULL(novsales,0)-ISNULL(decsales ,0)
FROM (
    SELECT saleskey,sum(salesamount) as novsales 
    FROM FactSales 
    WHERE month(DateKey) = 11 
    AND YEAR(DateKey) =2007 
    GROUP BY saleskey
) as a 
full outer join (
    SELECT saleskey,sum(SalesAmount) as decsales 
    FROM FactSales 
    WHERE month(DateKey) = 12 
    AND YEAR(DateKey) =2007
    GROUP BY saleskey
) as b on a.SalesKey = b.SalesKey

但是.... 另一种较短的方法是像下面这样一次性完成

SELECT 
    saleskey,
    novsales = sum(CASE when month(DateKey) =11 then salesamount else 0 end) as novsales,
    decsales = sum(CASE when month(DateKey) =12 then salesamount else 0 end) as decsales,
    salesdiff=sum(CASE when month(DateKey) =11 then salesamount else 0 end) - sum(CASE when month(DateKey) =12 then salesamount else 0 end)
FROM FactSales 
WHERE month(DateKey) in ( 11 ,12)
AND YEAR(DateKey) =2007 
group by saleskey

答案 1 :(得分:1)

您的查询不必要地将表连接到自身,并在where中使用函数,这将对查询性能产生负面影响,因为您无法使用表上的任何索引。只需在case表达式中使用一些条件聚合:

select SalesKey
      ,sum(case when month(DateKey) = 11 then salesamount end)
       - sum(case when month(DateKey) = 12 then salesamount end) as SalesDiff
from FactSales 
where DateKey >= '20071101'
  and DateKey < '20080101'
group by SalesKey;

请注意,我正在将DateKey值与date值进行比较,并且查询正在寻找greater or equal to the start of Novemberless than the start of January。这是必需的,因为您正在使用datetime值来确保所有潜在的December记录。


再次查看您的问题,看来您可能是在歪曲您的数据,并且根本不想在SalesKey列上进行分组,这从名称上就可以理解。在这种情况下,您的查询甚至更简单:

select sum(case when month(DateKey) = 11 then salesamount end)
       - sum(case when month(DateKey) = 12 then salesamount end) as SalesDiff
from FactSales 
where DateKey >= '20071101'
  and DateKey < '20080101'

答案 2 :(得分:0)

如果这些是数字(应该是数字)

选择novsales,decsales,novsales-decsales作为差异

演示

declare @t table (int1 int, int2 int);
insert @t values (1,2), (5,3);
select *, int1 - int2 as diff
from @t

我认为语法将失败。您需要一个group by

SELECT saleskey, sum(salesamount) as novsales 
FROM FactSales 
WHERE month(DateKey) = 11 
AND YEAR(DateKey) = 2007 
group by saleskey