最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用SQL語句按照一定時間間隔填充時間的方法

 更新時間:2026年01月23日 09:41:43   作者:衡水世耀科技有限公司  
本文總結(jié)了在不同數(shù)據(jù)庫中按固定時間間隔補(bǔ)齊時間軸的SQL做法,涵蓋了PostgreSQL、MySQL、SQLServer、SQLite、BigQuery和Snowflake等常見數(shù)據(jù)庫,每種數(shù)據(jù)庫都有其特定的方法,感興趣的朋友跟隨小編一起看看吧

我們在工作當(dāng)中經(jīng)常會遇到填充時間軸的問題,我整理了一份通用“按固定時間間隔補(bǔ)齊時間軸”的SQL做法合集,覆蓋常見數(shù)據(jù)庫(PostgreSQL、MySQL、SQL Server、SQLite、BigQuery、Snowflake)。你可以選用與你環(huán)境匹配的版本。思路都一樣:

  1. 生成一條連續(xù)的時間序列(按分鐘/小時/天等間隔);
  2. 用這條時間序列和你的數(shù)據(jù)LEFT JOIN,對缺失點(diǎn)補(bǔ) 0 或空值;
  3. 再做需要的聚合(如每5分鐘求和/計數(shù)/均值)。

1) PostgreSQL / Amazon Redshift(推薦,最簡潔)

PostgreSQL 原生有 generate_series,寫法非常優(yōu)雅。

示例:每5分鐘補(bǔ)齊一次,統(tǒng)計每5分鐘事件數(shù)

WITH ts AS (
  SELECT generate_series(
           timestamp '2025-10-01 00:00:00',
           timestamp '2025-10-02 00:00:00',
           interval '5 minute'
         ) AS bucket
),
events AS (
  -- 你的原始數(shù)據(jù)表,假設(shè)字段:event_time (timestamp)
  SELECT date_trunc('minute', event_time) AS minute_ts
  FROM public.event_log
  WHERE event_time >= '2025-10-01 00:00:00'
    AND event_time <  '2025-10-02 00:00:00'
)
SELECT
  ts.bucket,
  COALESCE(cnt.c, 0) AS event_count
FROM ts
LEFT JOIN (
  SELECT date_trunc('minute', minute_ts) - (extract(minute FROM minute_ts)::int % 5) * interval '1 minute'
           AS bucket_5m,
         count(*) AS c
  FROM events
  GROUP BY 1
) cnt
ON ts.bucket = cnt.bucket_5m
ORDER BY ts.bucket;

如果你的數(shù)據(jù)已經(jīng)是整分,就可以把上面的“對5分鐘分箱”的表達(dá)式簡化成 date_trunc('minute', event_time) 再對 interval '5 minute' 進(jìn)行對齊。

每天/每小時序列只需把 interval '5 minute' 換成 interval '1 hour'interval '1 day',同時聚合邏輯改為 date_trunc('hour'/'day', ...)

2) MySQL 8.0+(使用遞歸CTE)

MySQL 沒有內(nèi)置的 generate_series,我們用遞歸CTE造序列。

示例:每15分鐘補(bǔ)齊一次

WITH RECURSIVE ts AS (
  SELECT TIMESTAMP('2025-10-01 00:00:00') AS bucket
  UNION ALL
  SELECT bucket + INTERVAL 15 MINUTE
  FROM ts
  WHERE bucket < '2025-10-02 00:00:00'
),
events AS (
  SELECT event_time
  FROM event_log
  WHERE event_time >= '2025-10-01 00:00:00'
    AND event_time <  '2025-10-02 00:00:00'
),
agg AS (
  SELECT
    -- 把 event_time 對齊到 15分鐘的時間桶
    FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(event_time) / (15*60)) * (15*60)) AS bucket_15m,
    COUNT(*) AS c
  FROM events
  GROUP BY 1
)
SELECT
  ts.bucket,
  COALESCE(agg.c, 0) AS event_count
FROM ts
LEFT JOIN agg
  ON ts.bucket = agg.bucket_15m
ORDER BY ts.bucket
OPTION MAX_RECURSION_DEPTH = 100000; -- 如有需要可調(diào)整

性能提示:長時間跨度建議用“輔助數(shù)字表/日歷表/時間維表”替代遞歸;或者先生成按天的序列再在應(yīng)用層擴(kuò)展。

3) SQL Server(兩種做法:遞歸CTE 或 Tally/Numbers 表)

3.1 遞歸CTE

WITH ts AS (
  SELECT CAST('2025-10-01T00:00:00' AS datetime2) AS bucket
  UNION ALL
  SELECT DATEADD(minute, 10, bucket)
  FROM ts
  WHERE bucket < CAST('2025-10-02T00:00:00' AS datetime2)
),
agg AS (
  SELECT DATEADD(minute,
                 DATEDIFF(minute, 0, event_time) / 10 * 10, 0) AS bucket_10m,
         COUNT(*) AS c
  FROM dbo.EventLog
  WHERE event_time >= '2025-10-01T00:00:00'
    AND event_time <  '2025-10-02T00:00:00'
  GROUP BY DATEADD(minute, DATEDIFF(minute, 0, event_time) / 10 * 10, 0)
)
SELECT ts.bucket,
       ISNULL(agg.c, 0) AS event_count
FROM ts
LEFT JOIN agg
  ON ts.bucket = agg.bucket_10m
ORDER BY ts.bucket
OPTION (MAXRECURSION 0);

3.2 Numbers/Tally 表(更高效,推薦生產(chǎn))

先準(zhǔn)備一個連續(xù)整數(shù)表(可持久化)。隨后:

DECLARE @start datetime2 = '2025-10-01T00:00:00';
DECLARE @end   datetime2 = '2025-10-02T00:00:00';

WITH ts AS (
  SELECT DATEADD(minute, n*5, @start) AS bucket
  FROM dbo.Numbers
  WHERE DATEADD(minute, n*5, @start) <= @end
)
-- 其余與上面 LEFT JOIN 聚合同理

4) SQLite(遞歸CTE)

WITH RECURSIVE ts(bucket) AS (
  SELECT DATETIME('2025-10-01 00:00:00')
  UNION ALL
  SELECT DATETIME(bucket, '+5 minutes')
  FROM ts
  WHERE bucket < '2025-10-02 00:00:00'
),
agg AS (
  SELECT
    DATETIME(STRFTIME('%s', event_time) / (5*60) * (5*60), 'unixepoch') AS bucket_5m,
    COUNT(*) AS c
  FROM event_log
  WHERE event_time >= '2025-10-01 00:00:00'
    AND event_time <  '2025-10-02 00:00:00'
  GROUP BY 1
)
SELECT ts.bucket, IFNULL(agg.c, 0) AS event_count
FROM ts
LEFT JOIN agg ON ts.bucket = agg.bucket_5m
ORDER BY ts.bucket;

5) BigQuery(原生數(shù)組函數(shù),非常方便)

WITH ts AS (
  SELECT
    ts AS bucket
  FROM UNNEST(
    GENERATE_TIMESTAMP_ARRAY(
      TIMESTAMP('2025-10-01 00:00:00+00'),
      TIMESTAMP('2025-10-02 00:00:00+00'),
      INTERVAL 15 MINUTE
    )
  ) AS ts
),
agg AS (
  SELECT
    TIMESTAMP_TRUNC(event_time, MINUTE) - 
      INTERVAL MOD(EXTRACT(MINUTE FROM event_time), 15) MINUTE AS bucket_15m,
    COUNT(*) AS c
  FROM `project.dataset.event_log`
  WHERE event_time >= TIMESTAMP('2025-10-01 00:00:00+00')
    AND event_time <  TIMESTAMP('2025-10-02 00:00:00+00')
  GROUP BY 1
)
SELECT ts.bucket, IFNULL(agg.c, 0) AS event_count
FROM ts
LEFT JOIN agg
  ON ts.bucket = agg.bucket_15m
ORDER BY ts.bucket;

6) Snowflake(使用 GENERATOR)

WITH params AS (
  SELECT
    TO_TIMESTAMP('2025-10-01 00:00:00') AS start_ts,
    TO_TIMESTAMP('2025-10-02 00:00:00') AS end_ts,
    5 AS step_min
),
ts AS (
  SELECT
    DATEADD(minute, seq4()*step_min, start_ts) AS bucket
  FROM params,
       TABLE(GENERATOR(ROWCOUNT => 100000000)) -- 上限要能覆蓋區(qū)間長度
  QUALIFY bucket <= (SELECT end_ts FROM params)
),
agg AS (
  SELECT
    DATE_TRUNC('minute', event_time) - 
      (DATE_PART(minute, event_time) % 5) * INTERVAL '1 minute' AS bucket_5m,
    COUNT(*) AS c
  FROM EVENT_LOG
  WHERE event_time >= (SELECT start_ts FROM params)
    AND event_time <  (SELECT end_ts   FROM params)
  GROUP BY 1
)
SELECT ts.bucket, COALESCE(agg.c, 0) AS event_count
FROM ts
LEFT JOIN agg ON ts.bucket = agg.bucket_5m
ORDER BY ts.bucket;

ROWCOUNT 要覆蓋足夠的時間點(diǎn):大致 = (總分鐘數(shù) / step_min) + 1。

通用“參數(shù)化模版”

把這段思想搬到任何庫都成立:

  1. 定義參數(shù)start_ts、end_tsstep(分鐘/小時/天)。
  2. 生成連續(xù)時間(遞歸CTE、內(nèi)置序列函數(shù)、Numbers表、數(shù)組生成等)。
  3. 對齊/分箱:把事實(shí)表時間戳落到 step 對齊的“時間桶”。
  4. LEFT JOIN + COALESCE:保證缺失點(diǎn)返回 0。
  5. ORDER BY 時間桶

常見坑 & 優(yōu)化建議

  • 對齊方式:例如 5 分鐘分箱要確保所有時間都落在 00,05,10,...,55 上。不同數(shù)據(jù)庫對齊寫法不同,上面示例已給出。
  • 閉區(qū)間/開區(qū)間:通常建議 [start, end),避免終點(diǎn)重復(fù)。
  • 時區(qū):原始數(shù)據(jù)如果是 UTC,聚合前先統(tǒng)一到目標(biāo)時區(qū)或全部用 UTC,然后在展示層轉(zhuǎn)時區(qū)。
  • 性能:長時間跨度用日歷表/Numbers 表最穩(wěn)。給時間列和分箱列加索引/分區(qū);盡量先裁剪時間范圍再聚合。
  • 重復(fù)數(shù)據(jù):分箱前先去重或定義清楚計數(shù)口徑。
  • 窗口邊界:如果做移動平均/滑動窗口,先補(bǔ)齊再用窗口函數(shù)。

到此這篇關(guān)于使用SQL語句按照一定時間間隔填充時間的方法的文章就介紹到這了,更多相關(guān)sql語句按照一定時間間隔填充時間內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

谷城县| 衡阳市| 和硕县| 天长市| 舞钢市| 扬州市| 萨迦县| 都昌县| 内丘县| 恩平市| 连云港市| 阳春市| 门头沟区| 宁明县| 五峰| 临海市| 武威市| 余庆县| 拉萨市| 工布江达县| 三亚市| 察隅县| 巴青县| 井研县| 平阳县| 清徐县| 南京市| 平湖市| 祁连县| 伊吾县| 孟村| 中江县| 宁化县| 镇江市| 聂荣县| 安丘市| 藁城市| 垫江县| 马公市| 五寨县| 淮南市|