【问题标题】:Sql cartesian product (summing with group by)Sql笛卡尔积(与分组求和)
【发布时间】:2018-02-17 05:06:02
【问题描述】:

我正在尝试计算表 important_stock_dates 中特定日期的一组股票过去三十天的交易量总和。表all_stock_dates 包含相同的股票,但所有日期的交易量,而不仅仅是特定日期。

样本数据

all_stock_dates

stockid, date, volume  
0231245, 20060314, 153  
0231245, 20060315, 154  
2135411, 20060314, 23  

important_stock_dates

stockid, date, thirtydaysprior  
0231245, 20060314, 20060130  
0231245, 20060315, 20060201  
2135411, 20060314, 20060130  

我的代码

create table sum_trading_volume as
select a.stockid, a.date, sum(b.volume) as thirty_day_volume
from important_stock_dates a, all_stock_dates b
where b.date<a.date AND b.date ge a.thirtydaysprior
group by a.stockid, a.date;

期望的结果

包含来自 important_stock_dates 的所有观察结果的表格,其中还包含基于 all_stock_dates 中匹配的 stockid 和日期的前 30 天的交易量总和。

问题

我遇到的问题是important_stock_dates 有 1500 万个观测值,而all_stock_dates 有 3.5 亿个观测值。它使用了数百 GB 的交换文件来运行此代码(使硬盘驱动器最大化)然后中止。我看不到如何优化代码。我在 StackOverflow 或 Google 上找不到类似的问题。

【问题讨论】:

  • (1) 提供样本数据和期望的结果。 (2) 用您正在使用的数据库标记您的问题。
  • 今日提示:切换到现代、明确的JOIN 语法。更容易编写(没有错误),更容易阅读(和维护),并且在需要时更容易转换为外连接。
  • 它不是笛卡尔积,因为实际上在WHERE 子句中隐藏了一个连接条件,q.v。上面@jarlh 的评论。
  • 您加入了一个important_stock_dates 与所有all_stock_dates 记录,日期在thirtydayspriordate 之间。对于 important_stock_dates 记录,通常有多少 all_stock_dates 记录与此条件匹配? 1? 20? 30?还是100,000?在应用聚合(volume 的总和)之前,您将 1500 万个观测值乘以该数字。

标签: sql group-by sas query-optimization cartesian-product


【解决方案1】:

想必你想加入stockid的查询:

create table sum_trading_volume as
    select isd.stockid, isd.date, sum(asd.volume) as thirty_day_volume
    from important_stock_dates isd join
         all_stock_dates asd
         on isd.stockid = asd.stockid and
            asd.date < isd.date and asd.date >= isd.thirtydaysprior
    group by isd.stockid, isd.date;

如果这行得通,它可能会运行到完成。

【讨论】:

  • 好主意。也很高兴看到适当的别名和适当的连接:-)
  • 谢谢。这完美且非常快速(大约 6 分钟)。我试图理解你写的东西,所以我不会再犯同样的错误。知道为什么您的代码有效而我的无效吗?
  • @user6050 。 . .学习使用正确、明确的JOIN 语法。 从不FROM 子句中使用逗号。尽管您可以使查询与 WHERE 一起使用,但如果您使用适当的语法,则更有可能编写正确的查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-22
  • 1970-01-01
  • 2013-01-15
  • 2012-05-20
相关资源
最近更新 更多