天天看點

nCoV疫情地圖項目組資料庫事務

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

nCoV疫情地圖項目組資料庫事務
nCoV疫情地圖項目組資料庫事務
nCoV疫情地圖項目組資料庫事務

歡迎大家體驗及提bug,通路請點開圖檔,長按下面二維碼,或者點選閱讀原文。

nCoV疫情地圖項目組資料庫事務

最後,是我負責的資料庫的一個比較有意思的需求闡述與解決方案。

需求簡單描述:給定一個初始日期,将源表中的資料根據省份确定每天的新增病例。需求具體描述:

現有如下表,我們稱它為源表吧:

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進行事務比對,就簡單很多。

nCoV疫情地圖項目組資料庫事務