你的工作開始了
閑扯
上一次你順利的完成了程序員哥哥布置的任務,你覺得終於可以歇一口氣了,暫時沒人看出你是個newbie。
但是樹欲靜而風不止。領導突然想看看現在的系統,畢竟領導也要對董事彙報工作,需要了解現在的運行狀況。
現在你的挑戰開始了。
領導的需求
- 查一下2018年3月15日遲到的有多少人;
- 查一下這一天最早上班的人和最晚下班的人;
- 查一下每天最晚下班的那個人
你的應對之道
作為一個DBA,你的應對之道有以下幾條:
- 建議領導招一個小弟,這種繁瑣低級別的工作應該讓小弟做;
- 老老實實寫SQL查數據;
- 辭職走人
很明顯只有第二條現實。
那麼我們一條一條的SQL來寫。
先說第一個需求,首先我們知道你的公司每天9點上班,那麼只要9點以後打卡的人都算遲到,這麼簡單粗暴的邏輯SQL也應該很好寫:
select * from tb1 where signinTime > 09:00:00 and signDate = 2018-03-15;
signinTime是打卡時間,signDate指打卡日期,那麼這句SQL的意思就是:從tb1這張表中找到打卡日期是2018年3月15號且打卡時間大於9點的所有記錄。
Suddenly,能發現你的工號赫然在列:10012,這下糟糕了,讓領導知道你遲到了豈不是很尷尬。不過還好你是DBA,可以隨便更改這些數據,於是你寫下了這樣一條SQL:
update tb1 set signinTime = 08:54:21 where signDate = 2018-03-15 and employeeId = 10012;
這個SQL也很好懂:更新tb1,將打卡日期是2018年3月15號且工號為10012的那條記錄的signinTime設置成8點54分21秒。
一切都是這麼的完美,SQL簡直不能再好寫,不需要像別的語言一樣關心實現細節,只需要告訴它你想幹什麼就可以了。
這之後開始做第二件事情:查一下2018年3月15日這一天最早上班和最早下班的人。
select empolyeeId, employeeName from tb1 where signDate = 2018-03-15 order by signTime limit 1;
這句的意思也很明顯:在tb1中找打卡日期是2018年3月15日這一天的所有記錄,並將這些記錄按照打卡時間排序,取第一條。
多麼自然的處理邏輯。SQL就是這樣,告訴他你要什麼就可以。
select empolyeeId, employeeName from tb1 where signDate = 2018-03-15 order by signoutTime desc limit 1;
這句的意思也很明顯:在tb1中找打卡日期是2018年3月15日這一天的所有記錄,並將這些記錄按照打卡下班時間倒序排序,取第一條。
接下來就要查查每天最晚下班的記錄了,我們寫SQL以前先理順邏輯,之前都是單獨一天里去查詢的,現在是好多好多天,總不能一條一條的SQL那樣寫吧?當然不能,我們會發現這種SQL實際上就是上面那個SQL的集合形式,無非是按照時間分組罷了。對,分組,SQL里有個group by,就是根據什麼屬性分組的意思,因此這個SQL就這麼自然地出來了:
select employeeId, employeeName, signDate, max(signoutTime) from tb1 group by signDate;
你可能會發現我說的和我做的不一樣,我說這個SQL實際上前一個SQL的集合,但是明顯這個SQL和上面的那個SQL完全不一樣。
這其實是我不太想寫的SQL,因為這個SQL在Oracle上一定會報錯,Oracle不允許在SQL里只寫選擇列的一部分,而我認為Oracle的做法是對的。
總結
你會發現SQL其實很好寫,如果你以前是個Java或者C程序員,你會發現SQL和這種命令式編程語言完全不一樣,你不需要關心具體如何實現,你只需要寫出你的需求即可。因此會有人說SQL是第四代編程語言。具體怎麼寫SQL,其實很多書上會講很多,而我還是推薦看《資料庫系統概論》裡面關於關係代數的部分,掌握了關係代數,再看那些書上寫的SQL就會很快掌握。
閑扯
這次的題圖是一個寫了不少數學算式的黑板,其實學計算機學到最後會發現很多東西無非是數學的計算機實現罷了。
數學工具的強大才能讓人類的技術強大。
艾薩克牛頓當年也是覺得手頭的數學工具不好用,才發明了微積分,而微積分則給了牛頓力學一雙翅膀。
我們計算機專業的祖師爺阿蘭圖靈也是一位數學家。
推薦閱讀: