SQL167 連續簽到領金幣

SQL167 連續簽到領金幣

題目描述

用戶行為日志表 tb_user_log

iduidartical_idin_timeout_timesign_in
110102021-07-07 10:00:002021-07-07 10:00:091
210102021-07-08 10:00:002021-07-08 10:00:091
310102021-07-09 10:00:002021-07-09 10:00:421
41010

2021-07-10 10:00:00

2021-07-10 10:00:091
510102021-07-11 23:59:552021-07-11 23:59:591
610102021-07-12 10:00:282021-07-12 10:00:501
710102021-07-13 10:00:28

2021-07-13 10:00:50

1
810202021-10-01 10:00:282021-10-01 10:00:501
910202021-10-02 10:00:012021-10-02 10:01:501
1010202021-10-03 10:00:552021-10-03 11:00:591
1110202021-10-04 10:00:452021-10-04 11:00:550
1210202021-10-05 10:00:532021-10-05 11:00:591
1310202021-10-06 10:00:452021-10-06 11:00:551

(uid-用戶ID, artical_id-文章ID, in_time-進入時間, out_time-離開時間, sign_in-是否簽到)

場景邏輯說明

  • artical_id-文章ID代表用戶瀏覽的文章的ID,特殊情況artical_id-文章ID0表示用戶在非文章內容頁(比如App內的列表頁、活動頁等)。注意:只有artical_id為0時sign_in值才有效。
  • 2021年7月7日0點開始,用戶每天簽到可以領1金幣,并可以開始累積簽到天數,連續簽到的第3、7天分別可額外領2、6金幣
  • 每連續簽到7天后重新累積簽到天數(即重置簽到天數:連續第8天簽到時記為新的一輪簽到的第一天,領1金幣)

問題

計算每個用戶2021年7月以來每月獲得的金幣數(該活動到10月底結束,11月1日開始的簽到不再獲得金幣)。結果按月份、ID升序排序。

:如果簽到記錄的in_time-進入時間和out_time-離開時間跨天了,也只記作in_time對應的日期簽到了

輸出示例

示例數據的輸出結果如下:

uidmonthcoin
10120210715
1022021107

解釋:

101在活動期內連續簽到了7天,因此獲得1*7+2+6=15金幣;

102在10.01~10.03連續簽到3天獲得5金幣

10.04斷簽了,10.05~10.06連續簽到2天獲得2金幣,共得到7金幣。


思路

參考大佬:題解 | #連續簽到領金幣# 解題思路總結_牛客博客

問題理解

我們需要計算每個用戶在2021年7月至10月期間,每月通過簽到獲得的金幣總數。簽到規則如下:

  1. 每天簽到可獲得1金幣
  2. 連續簽到第3天額外獲得2金幣
  3. 連續簽到第7天額外獲得6金幣
  4. 每連續簽到7天后重新開始計算(第8天視為新一輪的第1天)

解題思路

步驟1:提取有效簽到記錄

首先需要從用戶行為日志中篩選出符合條件的簽到記錄:

  • 時間范圍:2021-07-07至2021-10-31
  • 文章ID為0(表示在非文章頁面)
  • 簽到位為1(表示成功簽到)
SELECT DISTINCTuid,DATE(in_time) AS sign_date
FROM tb_user_log
WHERE in_time BETWEEN '2021-07-07 00:00' AND '2021-10-31 23:59'AND artical_id = 0AND sign_in = 1

步驟2:識別連續簽到分組

為了計算連續簽到天數,我們使用一個技巧:用簽到日期減去行號,相同結果的日期屬于同一連續簽到組

SELECT uid,sign_date,DATE_SUB(sign_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY uid ORDER BY sign_date) DAY) AS group_date
FROM sign_dates

例如:

  • 用戶連續簽到3天:2021-07-07、2021-07-08、2021-07-09
  • 計算 group_date:
    • 2021-07-07 - 1天 = 2021-07-06
    • 2021-07-08 - 2天 = 2021-07-06
    • 2021-07-09 - 3天 = 2021-07-06
      這三個日期的 group_date 相同,表示它們是連續的

步驟3:計算連續簽到天數

在每組內,按日期排序并編號,得到連續簽到天數。

SELECT uid,sign_date,ROW_NUMBER() OVER (PARTITION BY uid, group_date ORDER BY sign_date) AS continuous_day
FROM sign_groups

步驟4:計算每日金幣

根據連續簽到天數計算每日獲得的金幣:

  • 第3天:1基礎金幣 + 2額外 = 3金幣
  • 第7天:1基礎金幣 + 6額外 = 7金幣
  • 其他天數:1金幣
SELECT uid,sign_date,CASE WHEN continuous_day % 7 = 3 THEN 3WHEN continuous_day % 7 = 0 THEN 7ELSE 1END AS coin
FROM continuous_days

步驟5:按月匯總金幣

最后,按用戶ID和月份分組,匯總金幣總數。

SELECT uid,DATE_FORMAT(sign_date, '%Y%m') AS month,SUM(coin) AS coin
FROM daily_coins
GROUP BY uid, DATE_FORMAT(sign_date, '%Y%m')
ORDER BY month, uid

關鍵點

  1. ?連續簽到識別?:通過日期減去行號的方法識別連續簽到組
  2. ?金幣計算規則?:正確處理第3天和第7天的額外金幣
  3. ?7天周期重置?:使用模運算(continuous_day % 7)實現7天后重置

代碼

WITH 
-- 獲取有效的簽到日期
sign_dates AS (SELECT DISTINCTuid,DATE(in_time) AS sign_dateFROM tb_user_logWHERE in_time BETWEEN '2021-07-07 00:00' AND '2021-10-31 23:59'AND artical_id = 0AND sign_in = 1
),-- 計算連續簽到分組
sign_groups AS (SELECT uid,sign_date,-- 計算連續簽到分組標識DATE_SUB(sign_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY uid ORDER BY sign_date) DAY) AS group_dateFROM sign_dates
),-- 計算每組內的連續簽到天數
continuous_days AS (SELECT uid,sign_date,-- 計算每組內的連續簽到天數ROW_NUMBER() OVER (PARTITION BY uid, group_date ORDER BY sign_date) AS continuous_dayFROM sign_groups
),-- 計算每日金幣
daily_coins AS (SELECT uid,sign_date,CASE WHEN continuous_day % 7 = 3 THEN 3  -- 第3天額外2金幣WHEN continuous_day % 7 = 0 THEN 7  -- 第7天額外6金幣ELSE 1                              -- 其他天1金幣END AS coinFROM continuous_days
)-- 最終按月匯總
SELECT uid,DATE_FORMAT(sign_date, '%Y%m') AS month,SUM(coin) AS coin
FROM daily_coins
GROUP BY uid, DATE_FORMAT(sign_date, '%Y%m')
ORDER BY month, uid;

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

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

相關文章

PHP性能優化與高并發處理:從基礎到高級實踐

引言 在當今高流量的互聯網環境中,PHP應用的性能優化變得至關重要。本文將全面探討PHP性能優化的各個層面,從基礎優化技巧到高級并發處理方案,幫助開發者構建高性能的PHP應用。 基礎性能優化 OPcache配置優化 ; php.ini 推薦OPcache配置 [opcache] opcache.enable=1 opc…

C++ std::map erase() 和迭代器詳解:常見面試陷阱與深入理解

在使用 C 的 std::map 時,配合 erase() 和迭代器的使用是一個經典面試點,也是實際開發中經常出錯的地方。本文將深入講解 erase() 的行為、end() 的本質以及迭代器失效規則,幫助你寫出更健壯的代碼。1. erase(it) 的行為當你使用 erase(it) 刪…

求職招聘小程序源碼搭建招聘小程序開發定制人力資源系統

身份:求職者、企業求職者:完善簡歷,簡歷投遞企業:企業入駐,查看簡歷企業會員:半年 、年度 權益:每日發布條數、刷新條數,簡歷下載數量聊天:求職者可以和企業聊天招聘會…

【31】C# WinForm入門到精通 ——保存文件SaveFileDialog 【屬性、方法、事件、實例、源碼】

WinForm 是 Windows Form 的簡稱,是基于 .NET Framework 平臺的客戶端(PC軟件)開發技術,是 C# 語言中的一個重要應用。 .NET 提供了大量 Windows 風格的控件和事件,可以直接拿來使用。 本專欄內容是按照標題序號逐漸…

socket網絡編程(1)

socket網絡編程(1) 設計echo server進行接口使用 生成的Makefile文件如下 .PHONY:all all:udpclient udpserverudpclient:UdpClient.ccg -o $ $^ -stdc17 -static udpserver:UdpServer.ccg -o $ $^ -stdc17.PHONY:clean clean:rm -f udpclient udpserver…

數據集:機器學習的基石

三、數據集:機器學習的基石1. sklearn 玩具數據集:快速入門的理想選擇1.1 玩具數據集的特點與價值sklearn 內置的玩具數據集(Toy Datasets)是機器學習入門的絕佳資源。這類數據集通常具有以下特點:數據量小&#xff1a…

SQL排查、分析海量數據以及鎖機制

1. SQL排查 1.1 慢查詢日志: mysql提供的一種日志記錄, 用戶記錄MySQL中響應時間超過閾值的SQL語句(long_query_time, 默認10秒), 慢查詢日志默認是關閉的, 建議開發調優時打開, 最終部署的時候關閉 1.1.1 檢查是否開啟了慢查詢日志 show variables like %slow_query_log%;臨…

conda 安裝prokka教程

本章教程,記錄如何在wsl2+ubuntu下載通過conda安裝prokka軟件包。 Prokka 是一個快速的、功能強大的基因組注釋工具,特別適用于細菌基因組的注釋。它能夠自動化完成從基因組序列到功能注釋的整個流程,包括基因的識別、功能預測和注釋,并且支持多種文件格式輸出,廣泛應用于…

CSS3 圓角

CSS3 圓角 引言 CSS3圓角是現代網頁設計中非常重要的一項功能,它使得網頁元素的外觀更加平滑、美觀。本文將詳細介紹CSS3圓角的概念、實現方法以及相關屬性,幫助您更好地掌握這一技巧。 CSS3圓角概念 CSS3圓角指的是通過CSS3屬性為元素(如div…

牛頓-拉夫森法求解非線性方程組

牛頓-拉夫森法(Newton-Raphson method)是一種用于求解非線性方程組的迭代方法。該方法通過線性化非線性方程組,并逐步逼近方程組的解。以下是牛頓-拉夫森法求解非線性方程組的詳細步驟和MATLAB實現。 1. 牛頓-拉夫森法的基本原理 對于非線性方…

Windows系統使用命令生成文件夾下項目目錄樹(文件結構樹)的兩種高效方法

Windows系統使用命令生成文件夾下項目目錄樹(文件結構樹)的兩種高效方法前言:**方法一:tree 命令 —— 快速生成經典目錄樹****方法二:PowerShell —— 可以精準過濾“降噪”的命令**這份列表非常精煉,只包…

react中暴露事件useImperativeHandle

注:本頁面模塊主要是使用 useImperativeHandle ,一、概述1、要點hooks 中的暴露事情件方法useImperativeHandle,需要和forwardRef、ref 結合一起使用。1、外層校驗的時候會校驗里面所有需要校驗的驗證2、基礎使用二、demo案例1、場景1、彈框打…

【論文閱讀】-《RayS: A Ray Searching Method for Hard-label Adversarial Attack》

RayS:一種用于硬標簽對抗攻擊的光線搜索方法 Jinghui Chen University of California, Los Angeles jhchencs.ucla.edu Quanquan Gu University of California, Los Angeles qgucs.ucla.edu 原文鏈接:https://arxiv.org/pdf/2006.12792 摘要 深度神經…

15K的Go開發崗,坐標北京

好久沒有分享最新的面經了,今天分享一下北京某公司Go開發崗的面經,薪資是15K左右,看看難度如何: 為什么要用分布式事務 分布式事務的核心作用是解決跨服務、跨數據源操作的數據一致性問題。在單體應用中,數據庫本地事務…

Linux 文件管理高級操作:復制、移動與查找的深度探索

目錄一、文件復制:從基礎到企業級同步的全維度解析1. cp命令:基礎工具的進階密碼(1)文件屬性保留:從基礎到極致(2)特殊文件處理:稀疏文件與設備文件(3)安全操…

Redis內存使用耗盡情況分析

目錄 1、內存上限介紹 1.1、產生原因 1.2、Redis的maxmemory限額 1.3、影響的命令與場景 2. 內存用完后的策略 2.1、淘汰策略分類 2.2、淘汰策略介紹 2.3、不同策略對比 3、常見業務示例 3.1、影響 3.2、監控與自動告警 前言 在日常項目中,不知道你思考過…

Ubuntu 系統中配置 SSH 服務教程

一、什么是 SSH?SSH(Secure Shell)是一種加密的網絡協議,用于在不安全的網絡中安全地進行遠程登錄、遠程命令執行和文件傳輸。它是 Telnet、FTP 等傳統協議的安全替代品。二、確認系統環境在開始配置之前,請確認你的系…

基于springboot的編程訓練系統設計與實現(源碼+論文)

一、開發環境 技術/工具描述MYSQL數據庫一個真正的多用戶、多線程SQL數據庫服務器,適用于Web站點或其他應用軟件的數據庫后端開發。B/S結構基于互聯網系統的軟件系統開發架構,利用瀏覽器進行訪問,支持多平臺使用。Spring Boot框架簡化新Spri…

K8s集群兩者不同的對外暴露服務的方式

在工作中,我們暴露集群內的服務通常有幾種方式,對于普通的http或者https,我們通常使用?Ingress Nginx? ,對于原始的TCP或者UDP端口服務,可能需要選擇 ?LoadBalancer? ,它們的核心區別在于工作層級、協議支持和流量…

實習日志111

第一天 加入內網和內網域,設置自己的操作系統 第二天 安裝常用軟件和平臺 Notepad 是一款免費的源代碼編輯器,支持多種編程語言,其功能強大且界面友好,適用于 Windows 操作系統。WinMerge 是一款開源的差異比較和合并工具&…