關於日期的經典SQL編程問題:生日問題

2021-01-14 IT168

  【IT168 技術】與日期相關的第一個問題是根據某個用戶的出生日期和當前日期,計算他最近的生日。通過對這個問題的處理,演示如何通過使用日期函數來正確處理閏月。

  在生日問題中,一般對閏月的處理如下:如果是閏月,那麼返回2月28日;如果不是閏月,則返回3月1日(大部分是出於法律的要求)。例如,當前的日期是2005年9月26日,有人出生在1972年2月29日,查詢後返回的該用戶最近的生日應該是2006年3月1日。如果當前是2007年9月26日,那麼查詢後應該返回2008年2月29日。

  在解決該問題之前,運行下列清單中的代碼,初始化一些數據。在演示前,需要確認已經安裝了MySQL官方的示例資料庫employees。

USE test;

CREATE TABLE employees LIKE employees.employees;

INSERT INTO employees
SELECT * FROM employees.employees LIMIT 10;

INSERT INTO employees
SELECT 10011,'1972-02-29','Jiang','David','M','1990-2-20';

  這裡人為地插入一個員工David Jiang,其出生日期為「1972-02-29」,閏月。運行如下語句得到所有員工的出生信息。

SELECT
    CONCAT(last_name,' ',first_name) AS Name,
    birth_date AS BirthDay
FROM employees;

  運行結果如下表所示。


▲每個員工的生日信息

  下面是該解決方案的SQL查詢:

SELECT name,birthday,
       IF(cur>today, cur,next) AS birth_day
FROM (
  SELECT name,birthday,today,
     DATE_ADD(cur, INTERVAL IF(DAY(birthday)=29
      && DAY(cur)=28,1,0) DAY) AS cur,
     DATE_ADD(next,INTERVAL IF(DAY(birthday)=29
      && DAY(next)=28,1,0) DAY) AS next
  FROM (
    SELECT name,birthday,today,
           DATE_ADD(birthday,INTERVAL diff YEAR) AS cur,
           DATE_ADD(birthday,INTERVAL diff+1 YEAR) AS next
    FROM (
      SELECT CONCAT(last_name,' ',first_name) AS Name,
             birth_date AS BirthDay,
             (YEAR(NOW())-YEAR(birth_date)) AS diff,
             NOW() AS today
     FROM employees ) AS a
    ) AS b
) AS c

  這個查詢需要a、b、c三個子查詢來完成。第一個子查詢a用來計算每位員工的出生日期與當前日期相差的年份,以及當前的日期。如果只運行子查詢a,將得到如下表所示的輸出,假設當前的日期為「2011-02-04」。


▲子查詢a的結果

  要計算某員工最近的生日,需要在BirthDay列加上Diff列的年數。如果結果大於當前日期,則年齡需要再加一年。子查詢b增加兩列即Cur和Next,這兩列分別用於表示今年和明年的生日。注意,如果出生日期是2月29日,且目標日期不是閏月,那麼這兩列所包含的將是2月28日,而不是3月1日。子查詢b的結果如下表所示。


▲子查詢b的結果

  子查詢c用來處理閏月的問題,如果出生的日期為閏月,並且當前的年份不是閏年,則日期加1,表示3月1日為生日。對下一個年份使用同樣的操作,子查詢c的結果如下表所示。


▲子查詢c的結果

  最後判斷今年的生日是否已過,如果是,則返回下一年的生日,最後得到的查詢結果如下表所示。


▲最後得到的查詢結果

  可以看到Maliniak Kyoichi今年的生日已過,下一個生日是2012年,而David Jiang的生日是3月1日。

  作者簡介

  姜承堯(DavidJiang),《MySQL技術內幕:SQL編程》、《MySQL技術內幕:InnoDB存儲引擎》作者,資深MySQL資料庫專家,MySQL開源分支版本InnoSQL的創始人,獨立資料庫諮詢顧問。不僅擅長於資料庫的管理和維護,還擅長於資料庫的開發,同時一直致力於MySQL資料庫底層實現原理的研究和探索,對高性能資料庫和數據倉庫也有深刻而獨到的理解。目前就職於網易研究院,擔任後臺技術中心技術經理一職,從事MySQL資料庫底層以及雲的相關的開發工作。

相關焦點

  • 關於用出生日期查詢生日還有多少天的問題
    1 問題描述最近老師布置了一個家庭作業,其中有一個關於用命令行輸入用戶生日信息,然後計算其生日還有多少天,是星期幾的一個作業,我覺得這個問題非常有趣,所以就在此跟大家分享一下我是如何用JAVA實現這個問題的,若有不足之處,請大家提出和指正。
  • SQL 經典實例
    如果要我推薦一本提升 SQL 編程水平的書籍,我大概率會推薦這本書——《SQL 經典實例》。
  • server sql 作業 使用專題及常見問題 - CSDN
    use masterGO/* --開啟sql server代理sp_configure 'show advanced options', 1; GO RECONFIGURE; GO sp_configure 'Agent XPs', 1; GO RECONFIGURE GO*/--定義創建作業
  • 面向對象編程會被拋棄嗎?這五大問題不容忽視
    選自towardsdatascience作者:Rhea Moutafis機器之心編譯機器之心編輯部今天來講講面向對象編程中比較棘手的問題。20 世紀 60 年代,編程遇到了一個大問題:計算機還沒有那麼強大,需要以某種方式平衡數據結構和程序之間的能力。
  • 國考備考之速解星期日期問題
    2014年國家公務員錄用考試即將開始,在行測數量運算模塊中,「星期日期問題」也是時常被考察的一個考點。在國考中,經常被考察的形式主要有兩種, 第一種是關於星期問題的計算,這類問題的核心知識可以用兩句話來總結:一年就加一,閏年(月)再加一: 【例1】2005年7月1日是星期五,那麼2008年7月1日是星期幾?
  • SQL Server各種日期計算
    通常,你需要獲得當前日期和計算一些其他的日期,例如,你的程序可能需要判斷一個月的第一天或者最後一天。你們大部分人大概都知道怎樣把日期進行分割(年、月、日等),然後僅僅用分割出來的年、月、日等放在幾個函數中計算出自己所需要的日期!
  • 概率問題中的生日悖論,為什麼23人裡兩人同一天生日的機率超50%
    其實,當我們看到「有人生日相同」時,下意識地會用「與我生日相同」去推測,而實際上「與我生日相同」的概率確實非常小。於是,直覺告訴我們,「有人生日相同」的概率也很小。但是,「生日悖論」中真正的問題其實是23 人中至少有2 人以上生日相同的概率,而不論究竟是誰的生日。這與我們的直覺中預設的前提條件有著根本的不同。
  • 2021京考行測備考:日期問題你還在列表格嗎?
    本文整理2021京考行測備考:日期問題你還在列表格嗎? 北京公務員考試招錄專題 京考信息匯總日期問題是行測數量關係當中的一個題型,很多考生遇到日期問題總是選擇列表格,但是當遇到了複雜的日期問題便很頭疼了。其實日期問題有很多規律,一旦你了解了這些規律,當考場上再遇到日期問題也能迎刃而解了。
  • 2020省考公務員行測備考:日期問題你還在列表格嗎?
    日期問題是行測數量關係當中的一個題型,很多考生遇到日期問題總是選擇列表格,但是當遇到了複雜的日期問題便很頭疼了。其實日期問題有很多規律,一旦你了解了這些規律,當考場上再遇到日期問題也能迎刃而解了。今天小編給大家介紹日期問題的規律以及經典例題。
  • 3分鐘短文|Laravel SQL篩選兩個日期之間的記錄,怎麼寫?
    引言今天說一個細分的需求,在模型中,或者使用laravel提供的 Eloquent ORM 功能,構造查詢語句時,返回位於兩個指定的日期之間的條目。應該怎麼寫?本文通過幾個例子,為大家梳理一下。學習時間假設有一個模型 Reservation,我們查詢某個日期的預訂條目數,首先構造日期字符串,使用內置函數:$now = date('Y-m-d');返回當前日期。
  • 人人編程專班——和「智教搭建編程」不得不說的「緣」
    —烏申斯基自6月5日以來,河南經濟貿易技師學院人人編程專班的同學進行了為期兩周的智教搭建編程課程學習,在這半個多月的時間裡,有歡聲有笑語,也有心酸,但更多的是在成長這條路上,我們一直在前行。智教搭建編程課程主要分為故事分享、搭建講授、教案準備、實戰講練四個階段,故事分享環節旨在擴充學員們的知識準備量,搭建講授環節旨在加深同學們對教具教材的掌握,從而做到靈活使用,教案準備環節能夠塑造同學們嚴謹的授課思路,最後的實戰演練環節是對同學們不斷的檢測提升。部分項目任務展示每日的故事分享環節,同學們各自發揮所能,將最好的狀態展現在大家眼前。
  • 第02篇:SQL資料庫的四種基本操作「增刪改查」
    上述這些均與C、java等其他程式語言不同。本章主要講解資料庫的常規基本操作,即:增(insert)、刪(delete)、改(update)、查(select)四種操作。其中,查詢的使用頻率最高且語法規則較多,是本章學習的重點和難點。二、SQL腳本其實通過工具也可以實現增刪改查,但通過SQL語句來實現相關操作效率更高。
  • 一招解決表格日期混亂問題
    [PConline技巧]經常能看到一些日期格式混亂的表格,當一個表格經手多人時,你可能會看到「2012-3-1」,也可能會有「2013.2.20」、「12.4.10」、「2011/7/28」這樣五花八門的格式。當然這些數字全都代表著某個生日,但這樣的「生日」,肯定會給後期的數據整理和分析帶來巨大的麻煩。今天小編就教給大家一個小技巧,一分鐘將這些不規則的日期「搞定」!
  • 經典:面向對象編程,我的思想(上部)
    學編程學的是什麼?思想!精通一門程式語言(最好是面向對象的語言)後再去搞其他的程式語言,你會發現過程是如此的行雲流水!為什麼?你已經把編程的思想掌握了,再去學其他的,無非是學習一種新的語法格式了。我在這裡並不是和你討論怎麼去用C++或JAVA,也不是和你討論怎麼去學他們,我要和你討論的是怎麼去理解面向對象。
  • 生日日期查女人性格,你是哪一類?
    -01-進取型(生日日期:1,5,8,10,14,15,17,23,25)性格解構:具有無比的獨立精神,酷愛自由討厭受束縛。頭腦清晰,腦筋轉得快,是個解決棘手問題的高手。-02-實幹型(生日日期:4,6,13,16,22,24,26,28,31)性格解構:這類型的女子通常都較為溫和穩重,腳踏實地。
  • SQL Server各種日期計算方法之一
    通常,你需要獲得當前日期和計算一些其他的日期,例如,你的程序可能需要判斷一個月的第一天或者最後一天。你們大部分人大概都知道怎樣把日期進行分割(年、月、日等),然後僅僅用分割出來的年、月、日等放在幾個函數中計算出自己所需要的日期!在這篇文章裡,我將告訴你如何使用DATEADD和DATEDIFF函數來計算出在你的程序中可能你要用到的一些不同日期。   在使用本文中的例子之前,你必須注意以下的問題。
  • 濟南機器人編程_山東機器人編程_機器人編程
    看到圖之後如何通過編程實現呢?首先編程思路圖:編程代碼如下:第一步:舞臺設計:第二步:角色設計(本程序至少需要三個角色,估計同學們已經看明白這些角色的作用了)詳細代碼如下:如果輸入五個數字,我們看看效果圖吧。同學們,你學會了嗎?好啦!
  • 我是計算機專業,身邊同行沒一個讓孩子在三年級前學編程
    然而只有我自己知道,我對編程依然是一竅不通,只能機械地做題,放到生活中完全不能解決實際問題。為了自學,我在網上找了麻省理工學院的編程公開課來看。課程一開始人家的老師就表示:我們這門課的主旨是在培養編程思維,程式語言只是幫助我們形成這種思維的工具。這句話讓我瞬間知道了自己的問題之所在,也是現在很多少兒編程教育的癥結:本末倒置。
  • 2020國家公務員考試行測數量關係技巧:日期問題
    2020國家公務員考試行測數量關係技巧:日期問題 2019-10-23 10:40:47| 中公教育 周麗紅
  • 熱血傳奇:有誰知道傳奇生日是哪一天?好幾個日期,老玩家只認它
    雖然大家對傳奇的感情非常深厚,但是有多少玩家知道傳奇遊戲的生日又是哪一天呢?其實關於這個日期很多玩家從來也沒關注過,不過今天貝斯手就帶大家一起來看看這個傳奇生日的問題。其實關於傳奇的生日也有很多說法,畢竟這是一個從韓國引進過來的遊戲,經歷不同地區運營的歷程,其中的就有不同的生日。