【问题标题】:Convert 15min to 10min timeseries in SQL Server在 SQL Server 中将 15 分钟转换为 10 分钟时间序列
【发布时间】:2021-01-08 01:14:38
【问题描述】:

我有一个 15 分钟格式的时间序列,包含四个不同的变量。我需要将其转换为 10 分钟时间序列格式。由于一些限制,我需要在 SQL 中执行此操作,我同意这可能是执行此操作的更糟糕的选择语言。但我确信它是可行的。

我认为需要做的是将每个 15 分钟的数据点分成三个 5 分钟的数据点,然后将每两个 5 分钟的数据点相加成一个 10 分钟的数据点。手动完成这会给我正确的结果。

下面是一些显示初始表的示例 DDL SQL:

IF OBJECT_ID('tempdb..#Temp15min') IS NOT NULL DROP TABLE #Temp15min

CREATE TABLE #Temp15min
(
    Project_id INT,
    Project_name VARCHAR(25),
    Date_results DATETIME,
    Pplus INT,
    Pminus INT,
    Qplus INT,
    Qminus INT,
    Zone VARCHAR(2)
)

INSERT INTO #Temp15min (Project_id, Project_name, Date_results, Pplus, Pminus, Qplus, Qminus, Zone)
VALUES 
(1, 'USA_Project', '2020-01-09 00:00',9879, 7766, 3886, 6628, 'US'),
(1, 'USA_Project', '2020-01-09 00:15', 15420, 10969, 5743, 9568, 'US'),
(1, 'USA_Project', '2020-01-09 00:30', 8763, 6602, 5475, 512, 'US'),
(1, 'USA_Project', '2020-01-09 00:45', 6998, 1083, 277, 13360, 'US'),
(1, 'USA_Project', '2020-01-09 01:00', 14356, 275, 1580, 14184, 'US'),
(1, 'USA_Project', '2020-01-09 01:15', 22983, 6161, 7815, 6917, 'US'),
(1, 'USA_Project', '2020-01-09 01:30', 7653, 5080, 2742, 8086, 'US'),
(1, 'USA_Project', '2020-01-09 01:45', 276, 14977, 10318, 3485, 'US')

最终结果表:

IF OBJECT_ID('tempdb..#Temp10min') IS NOT NULL DROP TABLE #Temp10min

CREATE TABLE #Temp10min
(
    Project_id INT,
    Project_name VARCHAR(25),
    Date_results DATETIME,
    Pplus INT,
    Pminus INT,
    Qplus INT,
    Qminus INT,
    Zone VARCHAR(2)
)

INSERT INTO #Temp10min (Project_id, Project_name, Date_results, Pplus, Pminus, Qplus, Qminus, Zone)
VALUES 
(1, 'USA_Project', '2020-01-09 00:00', 6586, 5177, 2591, 4419, 'US'),
(1, 'USA_Project', '2020-01-09 00:10', 8433, 6245, 3210, 5399, 'US'),
(1, 'USA_Project', '2020-01-09 00:20', 10280, 7313, 3829, 6379, 'US'),
(1, 'USA_Project', '2020-01-09 00:30', 5842, 4401, 3650, 341, 'US'),
(1, 'USA_Project', '2020-01-09 00:40', 5254, 2562, 1917, 4624, 'US'),
(1, 'USA_Project', '2020-01-09 00:50', 4665, 722, 185, 8907, 'US'),
(1, 'USA_Project', '2020-01-09 00:00', 9571, 183, 1053, 9456, 'US'),
(1, 'USA_Project', '2020-01-09 00:10', 12446, 2145, 3132, 7034, 'US'),
(1, 'USA_Project', '2020-01-09 00:20', 15322, 4107, 5210, 4611, 'US'),
(1, 'USA_Project', '2020-01-09 00:30', 5102, 3387, 1828, 5391, 'US'),
(1, 'USA_Project', '2020-01-09 00:40', 2643, 6686, 4353, 3857, 'US'),
(1, 'USA_Project', '2020-01-09 00:50', 184, 9985, 6879, 2323, 'US')

进行完整性检查以确保数字从头到尾都是正确的:

SELECT Project_id, Project_name, SUM(Pplus) PplusTotal, SUM(Pminus) PminusTotal, Sum(Qplus) QplusTotal, Sum(Qminus) QminusTotal, Zone FROM #Temp15min GROUP BY Project_id, Project_name, Zone
UNION
SELECT Project_id, Project_name, SUM(Pplus), SUM(Pminus), Sum(Qplus), Sum(Qminus), Zone FROM #Temp10min GROUP BY Project_id, Project_name, Zone

从图形上看,转换是这样的:

  • 左表是 15 分钟的数据点
  • 中表是 5 分钟的数据点
  • 右表是 10 分钟的数据点

我了解请求的复杂性,因此非常感谢任何帮助!

【问题讨论】:

    标签: sql sql-server datetime time-series


    【解决方案1】:

    根据您的描述,您可以“取消透视”每一分钟,然后重新汇总:

    select Project_id, Project_name, min(dateadd(minute, v.minutes, t.dateresults)) as dt,
           t.zone,
           sum(Pplus / 3.0),
           sum(Pminus / 3.0),
           sum(Qplus / 3.0),
           sum(Qminus / 3.0)
    from #Temp15min t cross join
         (values (0), (5), (10)) v(minutes)
    group by convert(date, dateadd(minute, v.minutes, t.dateresults)),
             datepart(hour, dateadd(minute, v.minutes, t.dateresults)),
             datepart(minute, dateadd(minute, v.minutes, t.dateresults)) / 6,
             Project_id, Project_name, zone;
    

    【讨论】:

    • 我应该指定我正在使用 SQL Server,所以我不能按原样使用日期函数。我以为我可以将其转换为 group by CONVERT(datetime,(dateadd(minute, v.minutes, t.dateresults))) 但我收到以下错误:“v”的列数比列列表中指定的多。
    • @amphinomos 。 . .日期功能很好。 value 子句中有错字。
    • 我得到一个“日期”不是一个可识别的内置函数名称。我还应该补充一点,我正在使用 2008 R2...我们应该很快就会升级。
    • @amphinomos 。 . .哎呀,我错过了。我把它改成了convert()
    • 仍然没有得到我想要的结果。感谢你目前的帮助。再次重新运行该练习时,我意识到由于以 kWh 为单位的数据的性质,存在一个额外的限制。将15min数据转换为5min数据和10min数据时,需要对实际数据进行按摩。第一个 15 分钟数据点 9879 成为第一个 5 分钟数据点 (9879/3) + (9879/3) = 6586 成为第一个 10 分钟数据点 (6586+6586)-(6586+6586)/4 = 9879。这个卷积计算允许原始总数不同,但分别除以 4、8 和 6 时是相等的。
    【解决方案2】:

    基于 Gordon Linoff 的回答以及 other stackoverflow post 并适应 SQL Server,我使用了以下代码:

    
    IF OBJECT_ID('tempdb..#Tempminutes') IS NOT NULL DROP TABLE #Tempminutes
    
    CREATE TABLE #Tempminutes
    (
        Minutes INT
    )
    
    INSERT INTO #Tempminutes VALUES (0),(5),(10)
    
    
    
    select Project_id, Project_name, min(dateadd(minute, v.minutes, t.date_results)) as dt,
           t.zone,
           sum(Pplus / 3.0),
           sum(Pminus / 3.0),
           sum(Qplus / 3.0),
           sum(Qminus / 3.0)
    from #Temp15min t cross join
         #Tempminutes v
    GROUP BY
            DATEPART(YEAR, dateadd(minute, v.minutes, t.date_results)),
            DATEPART(MONTH, dateadd(minute, v.minutes, t.date_results)),
            DATEPART(DAY, dateadd(minute, v.minutes, t.date_results)),
            DATEPART(HOUR, dateadd(minute, v.minutes, t.date_results)),
            (DATEPART(MINUTE, dateadd(minute, v.minutes, t.date_results)) / 10),
            Project_id, Project_name, zone
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 2021-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      相关资源
      最近更新 更多