Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 相对于上一年历史日期的销售额_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 相对于上一年历史日期的销售额

Sql 相对于上一年历史日期的销售额,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个包含销售交易的数据库。这些文件采用以下简化格式: sales_id | customer_id | sales_date | number_of_units | total_price 我的查询目标是针对这些交易中的每一笔,获取此特定客户id在当前记录之前、在此数据库的整个历史期间以及在当前记录之前的365天内的销售额 终身销售现在很有效,但最后365天的部分让我卡住了。我现在的查询可以识别记录在前365天内是否至少有一次销售,我这样做: SELECT sales_id ,custom

我有一个包含销售交易的数据库。这些文件采用以下简化格式:

sales_id | customer_id | sales_date | number_of_units | total_price
我的查询目标是针对这些交易中的每一笔,获取此特定客户id在当前记录之前、在此数据库的整个历史期间以及在当前记录之前的365天内的销售额

终身销售现在很有效,但最后365天的部分让我卡住了。我现在的查询可以识别记录在前365天内是否至少有一次销售,我这样做:

SELECT sales_id ,customer_id,sales_date,number_of_units,total_price,
    ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY sales_date ASC) as 'LifeTimeSales' ,
    CASE WHEN DATEDIFF(DAY,sales_date,LAG(sales_date, 1) OVER (PARTITION BY customer_id ORDER BY sales_date ASC)) > -365
         THEN 1 ELSE 0 END as 'Last365Sales'
 FROM sales_db
+一些不重要的WHERE子句。之后,我以其他方式聚合此查询的结果

但这并没有告诉我,例如,这是客户在过去365天内的第四次销售

注: 这是一个每天在拥有600万条记录且不断增长的完整数据库上运行的查询。我现在删除并重新创建这个表,这显然是没有效率的。当新的销售额进来时更新表是理想的,但是现在不可能创建。有什么想法吗

一些测试数据:

sales_id,customer_id,sales_date,number_of_units,total_price
1001,2001,2016-01-01,1,86
1002,2001,2016-08-01,3,98
1003,2001,2017-06-01,2,87
1004,2002,2017-06-01,2,15
+预期结果:

sales_id,customer_id,sales_date,number_of_units,total_price,LifeTimeSales,Last365Sales
1001,2001,2016-01-01,1,86,0,0
1002,2001,2016-08-01,3,98,1,1
1003,2001,2017-06-01,2,87,2,1
1004,2002,2017-06-01,2,15,0,0

对于销售前的销售计数,可以使用相关子查询

SELECT s1.sales_id,
       s1.customer_id,
       s1.sales_date,
       s1.number_of_units,
       s1.total_price,
       (SELECT count(*)
               FROM sales_db s2
               WHERE s2.customer_id = s1.customer_id
                     AND s2.sales_date <= s1.sales_date) - 1 lifetimesales,
       (SELECT count(*)
               FROM sales_db s2
               WHERE s2.customer_id = s1.customer_id
                     AND s2.sales_date <= s1.sales_date
                     AND s2.sales_date >= dateadd(day, s1.sales_date, -356)) - 1 last365sales
       FROM sales_db s1;

我使用s2.sales_date创建报告视图,其中所有必填字段都可用。 选择您需要的所有内容:

with all_history_statistics as 
(select customer_id, sales_id, sales_date, number_of_units, total_price,
    max(sales_date) over (partition by customer_id order by (select null)) as last_sale_date,
    count(sales_id) over (partition by customer_id order by (select null)) total_number_of_sales,
    count(sales_id) over (partition by customer_id order by sales_date asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_of_sales_for_current_date,
    sum(number_of_units) over (partition by customer_id order by (select null)) total_number_saled_units,
    sum(number_of_units) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_saled_units_for_current_date,
    sum(total_price) over (partition by customer_id order by (select null)) as total_earned,
    sum(total_price) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) earned_for_current_date)
from sales_db),
with last_year_statistics as 
(select customer_id, sales_id, sales_date, number_of_units, total_price,
    max(sales_date) over (partition by customer_id order by (select null)) as last_sale_date,
    count(sales_id) over (partition by customer_id order by (select null)) total_number_of_sales,
    count(sales_id) over (partition by customer_id order by sales_date asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_of_sales_for_current_date,
    sum(number_of_units) over (partition by customer_id order by (select null)) total_number_saled_units,
    sum(number_of_units) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_saled_units_for_current_date,
    sum(total_price) over (partition by customer_id order by (select null)) as total_earned,
    sum(total_price) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) earned_for_current_date)
from sales_db)
select <specify list of fields which you need>
from all_history_statistics t1 inner join last_year_statistics
on t1.customer_id = t2.cutomer_id 
;

表DDL+样本数据+预期结果可能会在几分钟内给您一个答案…请尝试@DmitrijKultasev我已经添加了样本数据+预期结果。@connorg98这不行。然后它只检查在过去365天是否有销售。你的问题让我困惑。您想在销售前进行销售盘点吗?或者你想列举销售额?但是,一列中的一个客户只能有一个枚举。但你希望它以某种方式相对于一行。但是有不止一行,所以不止一个枚举…好的,我昨天尝试了这个,但是它对我的数据库来说执行得太慢了。在运行了整整3个小时后,它只检索了600行,总数应该在200万左右,所以很遗憾,它在我的案例中不起作用。没有关于销售日期或客户id的索引可能并不理想…@JeroendeK:是的,索引可能会有所帮助。请在一个索引中的“客户id”、“销售日期”两列中各选一个,反之亦然,“销售日期”、“客户id”。看哪一个更好。@JeroendeK抱歉,我可能会错过这个。你能澄清一下这个查询没有返回哪些预期信息吗?上一年的统计数据和所有历史的统计数据是相同的,所以它没有给我相关的销售额。@JeroendeK,这是我的错。对不起,我会考虑如何改进我的答案,并尝试在短时间内回答。