连接具有不同数据维度的表(每周和每天)

Join Tables with different data dimensions (weekly and daily)

我有一个 table 每周采集数据,第二个 table 每天采集数据。我需要通过 id 键在 tables (INNER JOIN) 和每日 table 值之间建立联合,将它们平均每周汇总。

因此,我的结果 table 也将包含每周日期,并且对于每个星期,它应该显示前 7 天(包括获取当天)的 id 的平均值。

数据样本:DBfiddle

在提供的这个示例中,加入和分组操作返回了正确的结果。但是他取的是全局平均值,不是每个周采集日期对应的前7天的平均值。

有人知道解决这个问题的最佳方法吗?

子查询就足够了,但前提是您对每一行的最后 7 天都感兴趣

select id, rating, aquisition_date , 
(select avg(value) from table2 a2 where a2.id = a1.id and 
a2.aquisition_date between a1.aquisition_date - 6 and a1.aquisition_date) avg
from table1 a1

结果

id rating aquisition_date avg
1 10 2022-04-18 5
1 8.2 2022-04-25 14.57142

在附加示例中,您还提供了时间值(但由于 table 定义,它们在插入期间被切断)

简答: 您必须将周包括在 JOIN:

SELECT 
    table1.id
    ,EXTRACT(WEEK FROM table1.aquisition_date) AS week
    ,table1.rating AS table1_rating
    ,AVG(table2.value) as table2_value_avg
FROM 
    table1 table1
INNER JOIN 
    table2 table2
ON
    table2.id =   table1.id AND
    EXTRACT(WEEK FROM table1.aquisition_date) = EXTRACT(WEEK FROM table2.aquisition_date)
GROUP BY
    table1.id
   ,table1.rating
   ,table1.aquisition_date
;

这给了我们

id  week    table1_rating   table2_value_avg
1   17      8.2             20.0000000000000000
1   16      10              13.1428571428571429

长答案: 我们怎么去那里?考虑内部联接 没有 聚合:

您的第一次尝试是

SELECT 
    table1.id
    ,EXTRACT(WEEK FROM table1.aquisition_date) AS week1
    ,EXTRACT(WEEK FROM table2.aquisition_date) AS week2
--    ,AVG(EXTRACT(WEEK FROM table2.aquisition_date)) AS week2
    ,table1.rating AS table1_rating
    ,table2.value AS table2_value
--    ,AVG(table2.value) as table2_value_avg
FROM 
    table1 table1
INNER JOIN 
    table2 table2
ON
    table2.id =   table1.id

这将匹配两个表中不属于一起的行,例如第 15 周的值和第 16 周的评分。

id  week1   week2   table1_rating   table2_value
1   16      15      10              2
1   16      15      10              4
[... 40 more rows]

实际上它匹配表 1 和表 2 的每一行。这就是为什么平均值是全球平均值,即使 GROUP BY 有效。

所以上面的解决方案是从内部连接中删除那些星期不匹配的行。

N.B.: 如果你想在只有一个表有数据的结果中包含数据,你需要 FULL OUTER JOIN 但想法是一样的。

N.B.:(感谢@shawnt00)(从...中提取周)表示ISO 8601 week。它从星期一开始,一周可能还有其他定义。

N.B.:(感谢@shawnt00)该解决方案忽略了年份。如果存在超过一年的数据,您需要匹配 JOIN 中的年份和星期。