获取当前和去年销售额的SQL查询

获取当前和去年销售额的SQL查询,sql,oracle,Sql,Oracle,我有以下销售表: Date Store Sales 1/1/2015 St01 12123 1/1/2015 St02 3123 1/1/2016 St01 4213 1/1/2016 St03 2134 当我尝试自我加入以获得今年和去年的销售额时,关闭的商店没有出现。 结果应该是这样的: Date Store This year Sales Last Year Sales 1/1/2016 St01

我有以下销售表:

Date        Store   Sales
1/1/2015    St01    12123
1/1/2015    St02    3123
1/1/2016    St01    4213
1/1/2016    St03    2134
当我尝试自我加入以获得今年和去年的销售额时,关闭的商店没有出现。 结果应该是这样的:

Date        Store   This year Sales   Last Year Sales
1/1/2016    St01    4213              1212
1/1/2016    St02    0                 3123
1/1/2016    St03    2134              0
我的问题如下:

SELECT CY.DATE, 
       CY.store cy.Sales, 
       LY.sales 
FROM   sales CY, 
       sales LY 
WHERE  CY.store(+) = LY.store(+) 
       AND LY.DATE = CY.DATE - 365 

我只使用SQL Server。如果有什么不同,尝试应用相同的逻辑

声明临时表以测试查询:

实际查询:

结果:

工作原理:

完整连接将由商店和当前和前一年的生产线合并。 WHERE条款将按当前日期“2016年1月1日”过滤。允许为空,因为有时您没有当前或去年的行。 在列上,案例用于创建日期(如果当前日期为null,则为null),获取上一年+1年,反之亦然,用于创建存储(如果为null),并在销售列上放置零而不是null。
我只使用SQL Server。如果有什么不同,尝试应用相同的逻辑

声明临时表以测试查询:

实际查询:

结果:

工作原理:

完整连接将由商店和当前和前一年的生产线合并。 WHERE条款将按当前日期“2016年1月1日”过滤。允许为空,因为有时您没有当前或去年的行。 在列上,案例用于创建日期(如果当前日期为null,则为null),获取上一年+1年,反之亦然,用于创建存储(如果为null),并在销售列上放置零而不是null。
您需要的是数据透视表。尽管Oracle有特定的子句来执行此操作,但您可以使用纯SQL和纯SQL来执行此操作,如下所示:

SELECT store, 
       SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) THEN 
             sales 
             ELSE 0 
           END) AS "This year Sales", 
       SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) - 1 THEN 
             sales 
             ELSE 0 
           END) AS "Last year Sales" 
FROM   sales 
WHERE  Extract(year FROM DATE) >= Extract(year FROM SYSDATE) - 1 
GROUP  BY store 
ORDER  BY store 
SELECT ISNULL(CY.DATE, LY.DATE) as DATE, 
       ISNULL(CY.store, LY.store) as STORE,
       isnull(cy.Sales, 0), 
       isnull(LY.sales, 0) 
FROM   sales CY FULL OUTER JOIN sales LY 
    ON CY.store = LY.store
       AND (CY.DATE IS NULL OR 
            DATEPART(year, LY.DATE) = DATEPART(year, CY.DATE) - 1 
它将表明:

Store    This year Sales    Last year Sales
St01     4213               12123
St02     0                  3123
St03     2134               0
请注意,将列date作为第一列是没有意义的。您无法按它分组以显示所需的输出


在fiddle上查看此查询的等效项:

您需要的是数据透视表。尽管Oracle有特定的子句来执行此操作,但您可以使用纯SQL和纯SQL来执行此操作,如下所示:

SELECT store, 
       SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) THEN 
             sales 
             ELSE 0 
           END) AS "This year Sales", 
       SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) - 1 THEN 
             sales 
             ELSE 0 
           END) AS "Last year Sales" 
FROM   sales 
WHERE  Extract(year FROM DATE) >= Extract(year FROM SYSDATE) - 1 
GROUP  BY store 
ORDER  BY store 
SELECT ISNULL(CY.DATE, LY.DATE) as DATE, 
       ISNULL(CY.store, LY.store) as STORE,
       isnull(cy.Sales, 0), 
       isnull(LY.sales, 0) 
FROM   sales CY FULL OUTER JOIN sales LY 
    ON CY.store = LY.store
       AND (CY.DATE IS NULL OR 
            DATEPART(year, LY.DATE) = DATEPART(year, CY.DATE) - 1 
它将表明:

Store    This year Sales    Last year Sales
St01     4213               12123
St02     0                  3123
St03     2134               0
请注意,将列date作为第一列是没有意义的。您无法按它分组以显示所需的输出

在fiddle上查看此查询的等效项:

Oracle设置:

查询:

输出:

Oracle安装程序:

查询:

输出:

一般的解决方案是完全外部联接,它包括来自两个联接表的所有记录。我不知道Oracle语法,但在MS SQL Server中,它是这样的:

SELECT store, 
       SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) THEN 
             sales 
             ELSE 0 
           END) AS "This year Sales", 
       SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) - 1 THEN 
             sales 
             ELSE 0 
           END) AS "Last year Sales" 
FROM   sales 
WHERE  Extract(year FROM DATE) >= Extract(year FROM SYSDATE) - 1 
GROUP  BY store 
ORDER  BY store 
SELECT ISNULL(CY.DATE, LY.DATE) as DATE, 
       ISNULL(CY.store, LY.store) as STORE,
       isnull(cy.Sales, 0), 
       isnull(LY.sales, 0) 
FROM   sales CY FULL OUTER JOIN sales LY 
    ON CY.store = LY.store
       AND (CY.DATE IS NULL OR 
            DATEPART(year, LY.DATE) = DATEPART(year, CY.DATE) - 1 
如果a不为空,则b给出a,否则b给出。DATEPART提取日期的指定部分;我比较的是一年的差异,而不是365天的差异,如果去年是闰年,一般的解决方案是完全外部联接,它包括两个联接表中的所有记录。我不知道Oracle语法,但在MS SQL Server中,它是这样的:

SELECT store, 
       SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) THEN 
             sales 
             ELSE 0 
           END) AS "This year Sales", 
       SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) - 1 THEN 
             sales 
             ELSE 0 
           END) AS "Last year Sales" 
FROM   sales 
WHERE  Extract(year FROM DATE) >= Extract(year FROM SYSDATE) - 1 
GROUP  BY store 
ORDER  BY store 
SELECT ISNULL(CY.DATE, LY.DATE) as DATE, 
       ISNULL(CY.store, LY.store) as STORE,
       isnull(cy.Sales, 0), 
       isnull(LY.sales, 0) 
FROM   sales CY FULL OUTER JOIN sales LY 
    ON CY.store = LY.store
       AND (CY.DATE IS NULL OR 
            DATEPART(year, LY.DATE) = DATEPART(year, CY.DATE) - 1 

如果a不为空,则b给出a,否则b给出。DATEPART提取日期的指定部分;我比较的是一年而不是365天的差异,以防去年是闰年/

因为我希望查询能够逐日返回销售额,所以我使用了答案并添加了日期,这样我就可以获得所有年份的数据

WITH AllYear AS
 (select to_date('2016-01-01', 'yyyy-mm-dd') + level - 1 AS dobs
    from dual
  connect by level <= 366)

SELECT dobs AS "DATE",
       Store,
       nvl(SUM(CASE
                 WHEN t.Date = dobs THEN
                  t.sales
               END),
           0) AS "This Year Sales",
       nvl(SUM(CASE
                 WHEN t.Date = dobs-365 THEN
                  t.sales
               END),
           0) AS "Last Year Sales"
  FROM Sales t,AllYear
 where dobs='01-Jan-2016'
 GROUP BY Store
 ORDER BY Store;

因为我希望查询返回逐日销售,所以我使用了answer并添加了日期,这样我就可以获得全年的数据

WITH AllYear AS
 (select to_date('2016-01-01', 'yyyy-mm-dd') + level - 1 AS dobs
    from dual
  connect by level <= 366)

SELECT dobs AS "DATE",
       Store,
       nvl(SUM(CASE
                 WHEN t.Date = dobs THEN
                  t.sales
               END),
           0) AS "This Year Sales",
       nvl(SUM(CASE
                 WHEN t.Date = dobs-365 THEN
                  t.sales
               END),
           0) AS "Last Year Sales"
  FROM Sales t,AllYear
 where dobs='01-Jan-2016'
 GROUP BY Store
 ORDER BY Store;

您是否需要YRU结果中的第一列日期?是的,我也需要它用于每周和每月的销售。您甚至需要YRU结果中的第一列日期吗?是的,我也需要它用于每周和每月的销售。您的答案是针对SQLServer而不是oracle。oracle中没有dateadd函数。请使用add_monthsCY.Date,12而不是dateadd then。抱歉,这是oracle特有的问题。你的问题中有很多东西根本帮不上忙。事实上,OP甚至会让他感到困惑。另外,完全联接完全不需要联接,因为这只是一个旋转问题。您的答案是针对SQLServer而不是oracle的。oracle中没有dateadd函数。请使用add_monthsCY.Date,12而不是dateadd then。抱歉,这是oracle特有的问题。你的问题中有很多东西根本帮不上忙。事实上,OP甚至会让他感到困惑。此外,完全联接完全不需要联接,因为这只是一个旋转问题。这不是MS SQL,也不是完全联接或任何与联接相关的问题。这是一个数据透视问题。这不是MS SQL,也不是完整、联接或任何与联接相关的问题。这是一个关键性的问题。谢谢你给出了一个非常好的答案,所以这将是全年销售额的总和,但是如果我想一周一周、一个月一个月地做这件事,那该怎么办呢?那么你就必须将日期分为这些时段。这种提取物可以很容易地按月提取。对于本周来说,这将是一个更复杂的一点,因为提取到它,你w
我们必须使用一个组合,如“数字”到“图表”日期“2016年1月1日”,“MM/DD/YYYY”,“WW”,返回周数,然后您可以按周数分组,但您必须有句点,现在只有日期。你应该问一个新问题。这是完全不同的。请选择更适合您的问题的答案,并将其标记为已接受。这对其他人会有帮助。谢谢你给出了一个非常好的答案,所以这将是全年销售额的总和,但是如果我想每周和每月都这样做呢?那么你就必须将日期分为这些时段。这种提取物可以很容易地按月提取。对于一周来说,它会有点复杂,因为提取到它之后,你必须使用一个组合,比如“数字”到“图表”日期“2016年1月1日”,“MM/DD/YYYY”,“WW”,返回周数,然后你可以按它分组,但你必须有句点,现在你只有日期。你应该问一个新问题。这是完全不同的。请选择更适合您的问题的答案,并将其标记为已接受。它会帮助别人。