SQL思路解析:窗口滑動的應用

目錄

🎯 問題目標

第一步:從數據中我們能直接得到什么?

第二步:我們想要的“7天窗口”長什么樣?

第三步:SQL 怎么表達“某一天的前六天”?

🔍JOIN 比窗口函數更靈活

第四步:每個窗口要計算什么?

第五步:怎么避免不滿 7 天的窗口?

最終完整 SQL


表: Customer+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| customer_id   | int     |
| name          | varchar |
| visited_on    | date    |
| amount        | int     |
+---------------+---------+
在 SQL 中,(customer_id, visited_on) 是該表的主鍵。
該表包含一家餐館的顧客交易數據。
visited_on 表示 (customer_id) 的顧客在 visited_on 那天訪問了餐館。
amount 是一個顧客某一天的消費總額。

你是餐館的老板,現在你想分析一下可能的營業額變化增長(每天至少有一位顧客)。

計算以 7 天(某日期 + 該日期前的 6 天)為一個時間段的顧客消費平均值。average_amount?要?保留兩位小數。

結果按?visited_on?升序排序。

返回結果格式的例子如下。

示例 1:輸入:
Customer 表:
+-------------+--------------+--------------+-------------+
| customer_id | name         | visited_on   | amount      |
+-------------+--------------+--------------+-------------+
| 1           | Jhon         | 2019-01-01   | 100         |
| 2           | Daniel       | 2019-01-02   | 110         |
| 3           | Jade         | 2019-01-03   | 120         |
| 4           | Khaled       | 2019-01-04   | 130         |
| 5           | Winston      | 2019-01-05   | 110         | 
| 6           | Elvis        | 2019-01-06   | 140         | 
| 7           | Anna         | 2019-01-07   | 150         |
| 8           | Maria        | 2019-01-08   | 80          |
| 9           | Jaze         | 2019-01-09   | 110         | 
| 1           | Jhon         | 2019-01-10   | 130         | 
| 3           | Jade         | 2019-01-10   | 150         | 
+-------------+--------------+--------------+-------------+
輸出:
+--------------+--------------+----------------+
| visited_on   | amount       | average_amount |
+--------------+--------------+----------------+
| 2019-01-07   | 860          | 122.86         |
| 2019-01-08   | 840          | 120            |
| 2019-01-09   | 840          | 120            |
| 2019-01-10   | 1000         | 142.86         |
+--------------+--------------+----------------+
解釋:
第一個七天消費平均值從 2019-01-01 到 2019-01-07 是restaurant-growth/restaurant-growth/ (100 + 110 + 120 + 130 + 110 + 140 + 150)/7 = 122.86
第二個七天消費平均值從 2019-01-02 到 2019-01-08 是 (110 + 120 + 130 + 110 + 140 + 150 + 80)/7 = 120
第三個七天消費平均值從 2019-01-03 到 2019-01-09 是 (120 + 130 + 110 + 140 + 150 + 80 + 110)/7 = 120
第四個七天消費平均值從 2019-01-04 到 2019-01-10 是 (130 + 110 + 140 + 150 + 80 + 110 + 130 + 150)/7 = 142.86

?來源:Leecode


🎯 問題目標

先問自己最本質的問題:

?我想得到的到底是什么?

你想得到:

  • 某一天(比如 2019-01-07)為 窗口最后一天

  • 以它為終點往前推 6 天(共 7 天)的所有消費數據

  • 求這 7 天的總消費額和平均消費額(平均保留兩位小數)

  • 然后按日期升序列出每個窗口的情況

第一步:從數據中我們能直接得到什么?

我們原始數據是:

| customer_id | name  | visited_on | amount |
|-------------|-------|------------|--------|
| 1           | Jhon  | 2019-01-01 | 100    |
| 2           | Daniel| 2019-01-02 | 110    |
| ...         | ...   | ...        | ...    |

這是“按顧客”記錄的交易數據。

原始數據是“每個顧客某天消費了多少”,而我們不關心顧客是誰,只關心 每一天總共有多少消費。?

為了達成這個目標,你最小的可操作單位是:

? 每一天的“總營業額”

所以,第一步我們應該做的是:

SELECTvisited_on,SUM(amount) AS total_amount
FROM Customer
GROUP BY visited_on

?得到了:

| visited_on | total_amount |
|------------|--------------|
| 2019-01-01 | 100          |
| 2019-01-02 | 110          |
| 2019-01-03 | 120          |
| ...        | ...          |

第二步:我們想要的“7天窗口”長什么樣?

比如你想分析 2019-01-07 這個窗口,它包括:

  • 2019-01-01

  • 2019-01-02

  • 2019-01-03

  • 2019-01-04

  • 2019-01-05

  • 2019-01-06

  • 2019-01-07

我們要把這 7 天的金額加總后求平均。

換句話說,對于每一個日期 D,你要去找所有日期 D',滿足:

D' >= D - 6 天 AND D' <= D,然后求 sum(amount)

第三步:SQL 怎么表達“某一天的前六天”?

想象一下,窗口要對比誰和誰?

我們要讓每一行(例如日期是 2019-01-10)“看見”自己之前 6 天的數據。但 SQL 是面向集合的語言,每一行默認不能看見其他行。

怎么讓一行“看到”它前面的幾天?答案是:自連接(JOIN)!

SELECTc1.visited_on,             -- 作為窗口的當前“右端點”c2.visited_on,             -- 被掃描比較的行
FROM (SELECT visited_on, SUM(amount) AS daily_totalFROM CustomerGROUP BY visited_on
) c1
JOIN (SELECT visited_on, SUM(amount) AS daily_totalFROM CustomerGROUP BY visited_on
) c2ON c2.visited_on BETWEEN DATE_SUB(c1.visited_on, INTERVAL 6 DAY) AND c1.visited_on

這個 JOIN 的意思是:

對于每一行 c1,找出所有 c2,使得 c2.visited_on 落在 c2?之前 6 天之內。

也就是說,每一行 c1?會配對出一個 7 天的“時間窗口”數據集 c2。

就像下面這個例子:

c1.visited_onc2.visited_on(符合條件)
2019-01-072019-01-01 ~ 2019-01-07
2019-01-082019-01-02 ~ 2019-01-08
2019-01-092019-01-03 ~ 2019-01-09
2019-01-102019-01-04 ~ 2019-01-10

你可以理解為:“c1?的每一天”,都配對了“過去七天的 c2”,這就模擬出“滑動窗口”的行為了!

🔍JOIN 比窗口函數更靈活

在“時間窗口”這種分析中,數據可能并不是每天都有,或者每天不止一條記錄,比如:

| visited_on   | amount |
|--------------|--------|
| 2024-01-01   | 100    |
| 2024-01-01   | 80     |
| 2024-01-03   | 200    |

這種不連續、一天多條的情況,用 OVER (ORDER BY visited_on ROWS ...) 是不靠譜的,因為行數 ≠ 時間!

JOIN 這種方式,直接按時間范圍配對,不依賴數據是否連續,每天有多少條都不影響。

第四步:每個窗口要計算什么?

你想要的就是:

  • c1.visited_on:當前窗口的最后一天

  • SUM(c2.amount):這 7 天的總金額

  • ROUND(SUM(c2.amount) / 7, 2):這 7 天的平均值(保留兩位小數)

第五步:怎么避免不滿 7 天的窗口?

比如當你分析 2019-01-02 時,它前面只有兩天的數據(01、02),這是 不滿 7 天的窗口,要排除掉。

這時候就要加一條語句:

HAVING COUNT(DISTINCT c2.visited_on) = 7

?意思是:只有當這 7 天真的有 7 個不同的日期數據,才納入最終結果。

最終完整 SQL

把上述分析組合起來,完整 SQL 如下:

SELECT c1.visited_on,SUM(c2.daily_total) AS amount,ROUND(SUM(c2.daily_total)/7, 2) AS average_amount
FROM (SELECT visited_on, SUM(amount) AS daily_totalFROM CustomerGROUP BY visited_on
) c1
JOIN (SELECT visited_on, SUM(amount) AS daily_totalFROM CustomerGROUP BY visited_on
) c2ON c2.visited_on BETWEEN DATE_SUB(c1.visited_on, INTERVAL 6 DAY) AND c1.visited_on
GROUP BY c1.visited_on
HAVING COUNT(c2.visited_on) = 7
ORDER BY c1.visited_on;
問題層級解釋
本質問題想知道某天 + 前六天的消費總和和平均
可直接獲取的數據每天的顧客消費記錄(可匯總)
怎么形成7天窗口用自連接 + 日期范圍:BETWEEN D - 6 AND D
如何計算匯總 amount,平均除以 7 并 ROUND
如何過濾不滿7天窗口HAVING COUNT(DISTINCT c2.visited_on) = 7
最終排序按 visited_on 升序展示

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85668.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85668.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85668.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決MyBatis參數綁定中參數名不一致導致的錯誤問題

前言 作為一名Java開發者&#xff0c;我在實際項目中曾多次遇到MyBatis參數綁定的問題。其中最常見的一種情況是&#xff1a;在Mapper接口中定義的參數名與XML映射文件中的占位符名稱不一致&#xff0c;導致運行時拋出Parameter xxx not found類異常。這類問題看似簡單&#x…

黑馬程序員TypeScript課程筆記—類型兼容性篇

類型兼容性的說明 因為傳入的時候只有一個參數 對象之間的類型兼容性 接口之間的類型兼容性 函數之間的類型兼容性&#xff08;函數參數個數&#xff09; 和對象的兼容性正好相反 函數之間的類型兼容性&#xff08;函數參數類型&#xff09; 函數參數的兼容性就不要從接口角度…

智能電視的操作系統可能具備哪些優勢

豐富的應用資源&#xff1a; 操作系統內置了應用商店&#xff0c;提供了豐富的應用資源&#xff0c;涵蓋視頻、游戲、教育等多個領域&#xff0c;滿足不同用戶的多樣化需求。用戶可以輕松下載并安裝所需的應用&#xff0c;享受更多元化的娛樂和學習體驗。 流暢的操作體驗&…

Xget 正式發布:您的高性能、安全下載加速工具!

您可以通過 star 我固定的 GitHub 存儲庫來支持我&#xff0c;謝謝&#xff01;以下是我的一些 GitHub 存儲庫&#xff0c;很有可能對您有用&#xff1a; tzst Xget Prompt Library 原文 URL&#xff1a;https://blog.xi-xu.me/2025/06/02/xget-launch-high-performance-sec…

精美的軟件下載頁面HTML源碼:現代UI與動畫效果的完美結合

精美的軟件下載頁面HTML源碼&#xff1a;現代UI與動畫效果的完美結合 在數字化產品推廣中&#xff0c;一個設計精良的下載頁面不僅能提升品牌專業度&#xff0c;還能顯著提高用戶轉化率。本文介紹的精美軟件下載頁面HTML源碼&#xff0c;通過現代化UI設計與豐富的動畫效果&…

麒麟v10+信創x86處理器離線搭建k8s集群完整過程

前言 最近為某客戶搭建內網的信創環境下的x8s集群&#xff0c;走了一些彎路&#xff0c;客戶提供的環境完全與互聯網分離&#xff0c;通過yum、apt這些直接拉依賴就別想了&#xff0c;用的操作系統和cpu都是國產版本&#xff0c;好在仍然是x86的&#xff0c;不是其他架構&…

Pycharm的使用技巧總結

目錄 一、高效便捷的快捷鍵 二、界面漢化處理 1.設置 2.插件 3.漢化插件安裝 三、修改字體大小、顏色 1.選擇文件-設置 2.選擇編輯器-配色方案-python 3.修改注釋行顏色 4.修改編輯器字體顏色 一、高效便捷的快捷鍵 序號快捷鍵功能場景效果1Ctrl /快速注釋/取消注釋…

安全編碼規范與標準:對比與分析及應用案例

在軟件開發領域&#xff0c;尤其是涉及安全關鍵系統的開發中&#xff0c;遵循編碼規范和標準是確保軟件質量和安全性的重要手段。除了CERT C、CERT Java和MISRA外&#xff0c;還有其他多個與安全相關的編碼規范和標準&#xff0c;以下是一些主要標準的對比說明&#xff1a; 一…

FFmpeg學習筆記

1. 播放器的架構 2. 播放器的渲染流程 3. ffmpeg下載與安裝 3.0 查看PC是否已經安裝了ffmpeg ffmpeg 3.1 下載 wget https://ffmpeg.org/releases/ffmpeg-7.0.tar.gz 3.2 解壓 tar zxvf ffmpeg-7.0.tar.gz && cd ./ffmpeg-7.0 3.3 查看配置文件 ./configure …

大寬帶怎么做

我有10個G的寬帶資源&#xff0c;怎樣運行P2P才能將收益巨大化&#xff0c;主要有以下幾種方式&#xff1a; 1.多設備匯聚模式&#xff1a;使用多臺支持千兆網絡的服務器或專用PCDN設備&#xff08;如N1盒子&#xff09;&#xff0c;將10條寬帶分別接入不同設備&#xff0c;通過…

pytorch基本運算-導數和f-string

引言 在前序對機器學習的探究過程中&#xff0c;我們已經深刻體會到人工智能到處都有微分求導運算&#xff0c;相關文章鏈接包括且不限于&#xff1a; BP神經網絡 邏輯回歸 對于pytorch張量&#xff0c;求導運算必不可少&#xff0c;所以本次就專門來學習一下。 f-string的用…

dvwa4——File Inclusion

LOW: 先隨便點開一個文件&#xff0c;可以觀察到url欄變成這樣&#xff0c;說明?page是dvwa當前關卡用來加載文件的參數 http://10.24.8.35/DVWA/vulnerabilities/fi/?pagefile1.php 我們查看源碼 &#xff0c;沒有什么過濾&#xff0c;直接嘗試訪問其他文件 在url欄的pag…

經典面試題:一文了解常見的緩存問題

在面試過程中&#xff0c;面試官的桌子上擺放著很多高頻的面試題&#xff0c;能否順利回答決定了你面試通過的概率。其中緩存問題就是其中的一份&#xff0c;可以說掌握緩存問題及解決方法是面試前必須準備的內容。那么緩存有什么典型的問題&#xff0c;出現的原因是什么&#…

生產環境中安裝和配置 Nginx 以部署 Flask 應用的詳細指南

在生產環境中部署 Flask 應用時&#xff0c;Nginx 常被用作反向代理服務器&#xff0c;與 WSGI 服務器&#xff08;如 Gunicorn&#xff09;協同工作。Nginx 可以處理靜態文件、提供 SSL/TLS 加密、實現負載均衡等功能。本文將詳細介紹如何在 Ubuntu/Debian 系統上安裝 Nginx&a…

鴻蒙進階——Mindspore Lite AI框架源碼解讀之模型加載詳解(一)

文章大綱 引言一、模型加載概述二、核心數據結構三、模型加載核心流程 引言 Mindspore 是一款華為開發開源的AI推理框架&#xff0c;而Mindspore Lite則是華為為了適配在移動終端設備上運行專門定制的版本&#xff0c;使得我們可以在OpenHarmony快速實現模型加載和推理等功能&…

AI煉丹日志-24 - MCP 自動操作 提高模型上下文能力 Cursor + Sequential Thinking Server Memory

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; Java篇&#xff1a; MyBatis 更新完畢目前開始更新 Spring&#xff0c;一起深入淺出&#xff01; 大數據篇 300&#xff1a; Hadoop&…

【仿muduo庫實現并發服務器】實現時間輪定時器

實現時間輪定時器 1.時間輪定時器原理2.項目中實現目的3.實現功能3.1構造定時任務類3.2構造時間輪定時器每秒鐘往后移動添加定時任務刷新定時任務取消定時任務 4.完整代碼 1.時間輪定時器原理 時間輪定時器的原理類似于時鐘&#xff0c;比如現在12點&#xff0c;定一個3點的鬧…

Windows10下搭建sftp服務器(附:詳細搭建過程、CMD連接測試、連接失敗問題分析解決等)

最終連接sftp效果 搭建sftp服務器 1、這里附上作者已找好的 freeSSHd安裝包 ,使用它進行搭建sftp服務器。 2、打開freeSSHd安裝包,進行安裝 (1)、選擇完全安裝 (2)、安裝完成后,對提示窗口選擇關閉 (3)、安裝完成后,提示是否安裝私有密鑰。我們選擇"是" (4)、安…

推薦幾個不錯的AI入門學習視頻

引言&#xff1a;昨天推薦了幾本AI入門書&#xff08;AI入門書&#xff09;&#xff0c;反響還不錯。今天&#xff0c;我再推薦幾個不錯的AI學習視頻&#xff0c;希望對大家有幫助。 網上關于AI的學習視頻特別多。有收費的&#xff0c;也有免費的。我今天只推薦免費的。 我們按…

點擊啟動「高效模式」:大騰智能 CAD 重構研發設計生產力

在制造業數字化轉型浪潮中&#xff0c;設計工具的革新正成為企業突破效率瓶頸的關鍵。傳統CAD軟件因本地硬件依賴、協作壁壘高筑、復雜場景響應遲緩等問題&#xff0c;長期困擾設計團隊。 大騰智能CAD依托華為云底座、自研幾何引擎及AI技術深度融合&#xff0c;為制造行業各細…