最近在nCoV項目組做資料庫業務。最後的成果如下:

歡迎大家體驗及提bug,通路請點開圖檔,長按下面二維碼,或者點選閱讀原文。
最後,是我負責的資料庫的一個比較有意思的需求闡述與解決方案。
需求簡單描述:給定一個初始日期,将源表中的資料根據省份确定每天的新增病例。需求具體描述:
現有如下表,我們稱它為源表吧:
id
省份
确診日期
病例數
備注
1
浙江省
2020/1/22
2
3
4
2020/1/21
5
6
7
8
2020/1/23
9
10
11
湖北省
2020/1/10
41
12
2020/1/16
13
2020/1/17
17
14
2020/1/18
59
15
2020/1/19
77
16
2020/1/20
60
18
105
19
62
20
除了上述三列,還有其他,比如具體病例描述等等。當然除了上述省份,日期還有不同的省份與日期。那麼需求來了,我們最終想根據上述資訊得到類似下表,我們稱它為目标表吧:
72
68
當然處理這兩個省份列還有其他省份。現在開始實際操作吧。
首先計算一下總共有多少個省份,直轄市等等。
中國共有23個省,4個直轄市,5個自治區,2個特别行政區,總共有23+4+5+2=34個,這個數字後面用,先記住。
省份表
入庫省份與id,這個id為表的主鍵,從1開始到34。
插入資料:
從需求中發現存在一個日期循環,"給定一個初始日期",有點像for循環的起始條件,在sql中也可以寫循環,那就是事務,下面我們先定義一下事務的基本骨架:
這裡有幾個非常重要點。
第一個是<code>date_format</code>函數,将目前日期設為最終日期,例如今天是2月10号,那麼就是計算1月10到2月10号 每個省每一天的新增病例。
第二個是<code>subdate</code>,這個函數是日期減法函數,上述意思就是i每次增加一天,也就是如果目前i為2020-01-10,增加1天下次循環就是2020-01-11。
第三個四目前事務的參數,參數為int,這個參數代表即将傳遞的是省份的id。前面我們得到的省份與id關系,也就是<code>province</code>表,就是在這裡使用。
最後,就是邏輯處理,如果我們直接從源表到目标表就比較複雜,是以這裡先抽取出一個臨時表<code>tmp</code>表。這個表結構如下:
将源表資料插入到臨時表,再從臨時表進行行轉列即可。
是以上述循環中的邏輯處理如下:
這個sql語句為嵌套查詢+插入,目的是将源表<code>master</code>中國的資料抽取出來插入到<code>tmp</code>表中。
由于确診日期有可能是<code>2020-01-10 23:59:00</code>這種格式,而我們隻需要前面<code>2020-01-10</code>,是以這個采用<code>LIKE</code>與<code>%</code>進行比對。
上述有<code>COLLATE utf8mb4_unicode_ci</code>目的是防止下面錯誤:
最後,我們周遊每個省份并調用寫好的事務,上述省份中34就是在這裡使用。
調用這個事務,結果就會存到<code>tmp</code>表中:
在<code>tmp</code>表中的資料就是純粹的資訊,如下:
備注:這個表是部分資訊,不全。
我們想将其進行行轉列,就完成了最後的需求。
23個省,4個直轄市,5個自治區,2個特别行政,總共34個,上述的case就不寫完了。<code>...</code>是省略符号,省略了其他省。當然也可以采用<code>province</code>查詢出來的id進行事務比對,就簡單很多。