SQLite | Case 子句
文章目錄
- 1. The CASE Statement
- 1.1 The CASE Statement
- 1.2 The “Zero/Null” CASE Trick
- 參考資料
相關文章:
SQL | 目錄
SQLite | Select
SQLite | Where
SQLite | Group by and Order by
1. The CASE Statement
我們在上一篇中介紹了 Group by 和 Order by,
接下來我們將使用 CASE 語句為符合不同條件的情況賦值。
-
使用Jupyter Notebook 運行 SQL 語句需安裝 ipython-sql
-
%sql 以及 %%sql 為在 Notebook 中運行 SQL 語句,在 SQLite 命令行或 SQLite Stiduo 中不需要 %sql 或 %%sql
載入 SQL 以及連接 SQLite:
本文將使用 weather_stations.db 數據庫,其中包含了 STATION_DATA 表。
%load_ext sql %sql sqlite:///DataBase/weather_stations.db 'Connected: @DataBase/weather_stations.db'1.1 The CASE Statement
一個 case 語句可以讓我們讓我們為每一個不同的條件語句匹配不同的值。
在使用時,你可以以 case 開始,以 end 結束,在這中間,你能用
where [condiction] then [value] 的表達來為不同條件賦值。
在你指定了不同的 condiction-value 組合后,還可以用 else 為沒有符合任何條件的
值指定一個默認值。舉個例子,我們可以將 wind_speed 歸入 wind_severity 類,大于 40
的為 HIGH,30 至 40 為 MODERATE,其他的都為 LOW:
| 34DDA7 | 2002 | 12 | 21 | 0.2 | LOW |
| 39537B | 1998 | 10 | 1 | 6.7 | LOW |
| C3C6D5 | 2001 | 5 | 18 | 4.3 | LOW |
| 145150 | 2007 | 10 | 14 | 2.5 | LOW |
| EF616A | 1967 | 7 | 29 | 1.2 | LOW |
事實上,我們可以忽略 AND wind_speed < 40 這個條件,因為 sql 從上至下讀取 case 語句,
那些符合 wind_speed >= 40 的記錄已經被賦值為 HIGH 并且不再進行第二個條件的判斷了,
所以能夠到達第二個條件語句的記錄必然是 wind_speed < 40* 的,因此可以簡寫為:
| 34DDA7 | 2002 | 12 | 21 | 0.2 | LOW |
| 39537B | 1998 | 10 | 1 | 6.7 | LOW |
| C3C6D5 | 2001 | 5 | 18 | 4.3 | LOW |
| 145150 | 2007 | 10 | 14 | 2.5 | LOW |
| EF616A | 1967 | 7 | 29 | 1.2 | LOW |
當你創建 case 語句時,還可以同時做一些強大的轉換。如使用 group by 語句對數據進行分組:
%%sql select year, casewhen wind_speed >= 40 then 'HIGH'when wind_speed >= 30 then 'MODERATE'else 'LOW' end as wind_severity, count(*) as record_count from station_data group by 1,2 limit 0,5; * sqlite:///DataBase/weather_stations.db Done.| 1930 | LOW | 5 |
| 1932 | LOW | 3 |
| 1933 | LOW | 6 |
| 1935 | LOW | 2 |
| 1936 | LOW | 18 |
1.2 The “Zero/Null” CASE Trick
在使用 case 語句時,還有一些奇技淫巧,如 “zero/null” CASE 技巧,讓你能夠
在一個 select 語句內實現在不同的聚合值上進行分組,這是你使用 where 所無法達到的。
因為 where 只能夠在所有值上判斷同一個條件,而 case 能夠每一種聚合值創建不同的條件語句。
假如說你想要將總降雨量 precipitation 分為兩列:有龍卷風時的總降雨量(tornado_precipitation)
和沒有龍卷風時的總降雨量(non_tornado_precipitation),然后按年月分組。這個邏輯需要用到兩列數據:
precipitation 和 tornado,但是你會怎么編寫代碼呢?
如果讓你寫的話,你就會發現無法在一個 where 語句中完成,除非將它們拆分為兩個 where語句,一個是
有龍卷風的,一個是沒有龍卷風的:
| 1937 | 7 | None |
| 1941 | 8 | 0.30000000000000004 |
| 1942 | 10 | 0 |
| 1943 | 1 | None |
| 1943 | 4 | 0.15000000000000002 |
| 1930 | 6 | 0 |
| 1930 | 10 | None |
| 1932 | 3 | 0 |
| 1933 | 3 | 0 |
| 1933 | 7 | None |
然而我們可以用一個 case 語句將這兩個查詢合并為一個,你可以將判斷是否有龍卷風的語句從
where 移到 case,并為不符合條件的賦值為 0,然后使用 sum 就可以了:
我們在使用 sum 聚合語句時,通過使不符合條件的值為 0 ,從而讓它不被算入 sum(因為加一個 0 相當于沒加)
%%sql select year, month, sum(case when tornado == 1 then precipitation else 0 end) as tornado_precipitation, sum(case when tornado == 0 then precipitation else 0 end) as non_tornado_precipitation from station_data group by year, month limit 0,5; * sqlite:///DataBase/weather_stations.db Done.| 1930 | 6 | 0 | 0 |
| 1930 | 10 | 0 | None |
| 1932 | 3 | 0 | 0 |
| 1933 | 3 | 0 | 0 |
| 1933 | 7 | 0 | None |
case 語句還可以做一些更復雜的聚合任務,如在使用 min 或 max 操作時,
可以使用 null 值來代替那些不符合條件的值(而不是 0)。如我們可以找出在有無龍卷風條件下的年最大降雨量:
| 1992 | 1.5 | 1.51 |
| 1993 | 1.18 | 2.13 |
| 1994 | 1.26 | 1.16 |
| 1995 | 0.91 | 0.35 |
| 1996 | 3.31 | 0.68 |
就像 where 子句一樣,你可以在 case 子句中使用布爾表達式(包含 and, or, not)。
你可以使用以下代碼來查詢 2000 年后有[下雨或冰雹]時每個月的平均氣溫:
%%sql select month, avg(case when rain or hail then temperature else null end)as avg_precipitation_temp, avg(case when NOT (rain or hail) then temperature else null end)as avg_non_precipitation_temp from station_data where year > 2000 group by month limit 0,5; * sqlite:///DataBase/weather_stations.db Done.| 1 | 35.624242424242425 | 41.794149908592324 |
| 2 | 33.802439024390246 | 38.9016233766234 |
| 3 | 46.61333333333332 | 49.22558823529411 |
| 4 | 49.02916666666667 | 52.33038194444437 |
| 5 | 55.89777777777778 | 58.90691489361702 |
參考資料
[1] Thomas Nield.Getting Started with SQL[M].US: O’Reilly, 2016: 47-52
相關文章:
SQL | 目錄
SQLite | SQLite 與 Pandas 比較篇之一
SQLite | Select 語句
SQLite | Where 子句
SQLite | Group by 與 Order by 子句
SQLite | Join 語句
SQLite | 數據庫設計與 Creat Table 語句
SQLite | Insert、Delete、Updata 與 Drop 語句
總結
以上是生活随笔為你收集整理的SQLite | Case 子句的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tensorboard出现OSError
- 下一篇: SQLite | Insert、Dele