获取上周每WEEK个号码的平均流量数据,并获取上周Traffic(D-7)的流量数据

例如,如果日期=2023年5月13日,则需要输出日期=2023年5月6日的交通数据(Traffic(D-7)

enter image description here

我设法得到了平均值,但不知道如何检索日期数据并将其完全输出

create table a
(
date  varchar(50),
Tname varchar(50),
Week varchar(5),
Traffic float
)

insert into  a values ('5/1/2023', 'ID1', '18', 7.98)
insert into  a values ('5/2/2023', 'ID1', '18', 4.44)
insert into  a values ('5/3/2023', 'ID1', '18', 5.66)
insert into  a values ('5/4/2023', 'ID1', '18', 10.01)
insert into  a values ('5/5/2023', 'ID1', '18', 9.41)
insert into  a values ('5/6/2023', 'ID1', '18', 6.71)
insert into  a values ('5/7/2023', 'ID1', '18', 8.24)
insert into  a values ('5/8/2023', 'ID1', '19', 8.97)
insert into  a values ('5/9/2023', 'ID1', '19', 6.74)
insert into  a values ('5/10/2023', 'ID1', '19', 6.45)
insert into  a values ('5/11/2023', 'ID1', '19', 9.33)
insert into  a values ('5/12/2023', 'ID1', '19', 8.08)
insert into  a values ('5/13/2023', 'ID1', '19', 8.36)


SELECT date, Tname, Week,
AVG(Traffic) OVER(PARTITION BY Week) AS AVTraffic
FROM a
ORDER BY week

http://sqlfiddle.com/#!18/538b7/3

推荐答案

首先,您需要修复表模式设计中的缺陷,并声明:

  • "DATE"类型的日期(而不是VARCHAR(50))
  • INT类型的周值(而不是VARCHAR(5))
  • 类型为DECIMAL的流量值(而不是FLOAT)
CREATE TABLE tab(
    DATE      DATE,
    Tname     VARCHAR(50),
    Week      INT,
    Traffic   DECIMAL(4,2)
);

一旦你执行了它,你可以通过以下方法来解决这个问题:

  • 为您一周中的每一天创建排名值,在日期上使用EXTRACT
  • 通过对上一步创建的排名进行划分,并根据Week_Numbers进行排序,提取前一周LAG的流量价值.
WITH cte AS (
    SELECT date, Tname, Week, Traffic,
           ROUND(AVG(Traffic) OVER(PARTITION BY Week), 2) AS AVGTraffic,
           EXTRACT(ISODOW FROM date) - 1                  AS week_day
    FROM tab
)
SELECT date, Tname, Week, 
       LAG(Traffic) OVER(PARTITION BY week_day ORDER BY Week) AS prevweek_traffic,
       AVGTraffic
FROM cte
ORDER BY Week, week_day

如果您意识到您的周(...、第17周、第18周、第20周、第21周等)之间可能有空洞,并且特别想要前一周的值(可能会丢失),则可以在LAG函数上添加一个筛选器,该筛选器判断一周和前一周是否连续:

...
CASE WHEN LAG(Week) OVER(PARTITION BY week_day ORDER BY Week) = Week-1
     THEN LAG(Traffic) OVER(PARTITION BY week_day ORDER BY Week) 
END
...

(仅代替LAG(Traffic) OVER(...))

Output:

date tname week prevweek_traffic avgtraffic
2023-05-01T00:00:00.000Z ID1 18 null
2023-05-02T00:00:00.000Z ID1 18 null
2023-05-03T00:00:00.000Z ID1 18 null
2023-05-04T00:00:00.000Z ID1 18 null
2023-05-05T00:00:00.000Z ID1 18 null
2023-05-06T00:00:00.000Z ID1 18 null
2023-05-07T00:00:00.000Z ID1 18 null
2023-05-08T00:00:00.000Z ID1 19 7.98
2023-05-09T00:00:00.000Z ID1 19 4.44
2023-05-10T00:00:00.000Z ID1 19 5.66
2023-05-11T00:00:00.000Z ID1 19 10.01
2023-05-12T00:00:00.000Z ID1 19 9.41
2023-05-13T00:00:00.000Z ID1 19 6.71

查看演示here.

该查询允许您的数据中存在任何类型的漏洞,如果这是必需的.

注:不需要最后ORDER BY条款.它在那里只是为了可视化的目的.

Sql相关问答推荐

为什么在这种情况下我不能使用LAG函数?

如何使用WSO2将空值传递给我的SQL Server存储过程?

LEFT JOIN不显示计数0我期望的方式

从自定义日期和时间开始,每月具有给定状态的公司数量

如何查询jsonb列是一个对象数组?

SQL子查询返回多个值错误

找到最新的连线

用户购买平台及金额统计

在一个子查询中签入ID';S,如果未返回,则签入另一个子查询

基于是否具有某些数据的关联表覆盖SELECT语句中的列值

仅在日期相隔时递增(Oracle SQL)

替换SQL Server XML中多处出现的 node 值

在presto sql中解析带有区域的时间格式

SQL Server - 判断 ids 层次 struct 中的整数 (id)

SQL 多个不满足的条件失败

带聚合函数的 percentile_cont

根据行号将列转置为没有任何id或键列的行

我需要遍历权重值表并确定每个权重是否有效

忽略与给定列匹配的行的 LAG 函数

遍历数据,计算每个月最后三天的总和