數據分析|SQL內置函數大全

SQL內置函數使用大全

本文中總結了SQL中經常使用的內置函數,包含通用聚合函數、安全檢測函數、數學統計函數、字符串函數html

通用聚合函數

語句 含義 示例
arbitrary(x) 隨機返回x列中的一個值。 latency > 100 | select arbitrary(method)
avg(x) 計算x列的算數平均值。 latency > 100 | select avg(latency)
checksum(x) 計算某一列的checksum,返回base64編碼。 latency > 100 | select checksum(method)
count(*) 表示全部的行數。 -
count(x) 計算某一列非null的個數。 latency > 100 | select count(method)
count(數字) count(數字),如count(1),等同於count(*),表示全部的行數。 -
count_if(x) 計算x=true的個數。 latency > 100 | select count_if(url like ‘%abc’)
geometric_mean(x) 計算某一列的幾何平均數。 latency > 100 | select geometric_mean(latency)
max_by(x,y) 返回當y取最大值時,x當前的值。 查詢延時最高的時候,對應的method:latency>100 | select max_by(method,latency)
max_by(x,y,n) 返回y最高的n行,對應的x的值。 查詢延時最高的3行,對應的method:latency > 100 | select max_by(method,latency,3)
min_by(x,y) 返回當y取最小值時,x當前的值。 查詢延時最低的請求,對應的method:* | select min_by(x,y)
min_by(x,y,n) 返回y最小的n行,對應的x的值。 查詢延時最小的3行,對應的method: * | select min_by(method,latency,3)
max(x) 返回最大值。 latency > 100| select max(inflow)
min(x) 返回最小值。 latency > 100| select min(inflow)
sum(x) 返回x列的和。 latency > 10 | select sum(inflow)
bitwise_and_agg(x) 對某一列的全部數值作and計算。 -
bitwise_or_agg(x) 對某一列的數值作or計算。 -

安全檢測函數

函數名 含義 樣例
security_check_ip 檢查IP是否安全,其中:返回1:命中,表示不安全返回0:未命中 select security_check_ip(real_client_ip)
security_check_domain 檢查Domain是否安全,其中:返回1:命中,表示不安全返回0:未命中 select security_check_domain(site)
security_check_url 檢查URL是否安全,其中:返回1:命中,表示不安全返回0:未命中 select security_check_domain(concat(host, url))

Map映射函數

函數 含義 示例
下標運算符[] 獲取map中某個Key對應的結果。
histogram(x) 按照x的每一個值進行GROUP BY並計算count。語法至關於select count group by x說明 返回結果爲JSON格式。 latency > 10 | select histogram(status),等同於latency > 10 | select count(1) group by status
histogram_u(x) 按照x的每一個值進行GROUP BY並計算count。說明 返回結果爲多行多列。 latency > 10 | select histogram(status),等同於latency > 10 | select count(1) group by status
map_agg(Key,Value) 返回Key、Value組成的map,並返回每一個Key隨機的Value。 latency > 100 | select map_agg(method,latency)
multimap_agg(Key,Value) 返回Key、Value組成的多Value map,並返回每一個Key的全部的Value。 latency > 100 | select multimap_agg(method,latency)
cardinality(x) → bigint 獲取map的大小。
element_at(map``, key) → V 獲取Key對應的Value。
map() → map`` 返回一個空的map。
map(array, array) → map`` 將兩個數組轉換成Key、Value組成的Map。 SELECT map(ARRAY[1,3], ARRAY[2,4]); — {1 -> 2, 3 -> 4}
map_from_entries(array>) → map`` 把一個多維數組轉化成map。 SELECT map_from_entries(ARRAY[(1, ‘x’), (2, ‘y’)]); — {1 -> ‘x’, 2 -> ‘y’}
map_concat(map1, map2, …, mapN) → map 求多個map的並集,若是某個Key存在於多個map中,則取最後一個。
map_filter(map, function) → map 請參見Lambda函數中map_filter函數。
map_keys(x) → array 獲取map中全部的Key並以array的形式返回。
map_values(x) → array 獲取map中全部的Value並以array的形式返回。

估算函數

桶是按照彙集程度均分的,每一個結果裏顯示這個區域的均值和個數python

函數 說明 示例
approx_distinct(x) 估算x列的惟一值的個數。 -
approx_percentile(x,percentage) 對於x列排序,找出大約處於percentage位置的數值。 找出位於一半位置的數值:approx_percentile(x,0.5)
approx_percentile(x, percentages) approx_percentile(x,percentage)用法相似,但能夠指定多個percentage,找出每一個percentage對應的數值。 approx_percentile(x,array[0.1,0.2])
numeric_histogram(buckets, Value) 對於數值列,分多個桶進行統計。即把Value一列,分到桶中,桶的個數爲buckets。返回內容爲每一個桶的Key及對應的count數值,至關於針對數值的select count group by說明 返回結果的格式爲JSON。 對於POST請求,把延時分爲10個桶,查看每一個桶的大小:method:POST | select numeric_histogram(10,latency)
numeric_histogram_u(buckets, Value) 對於數值列,分多個桶進行統計。即把Value一列,分到桶中,桶的個數爲buckets。返回內容爲每一個桶的Key及對應的count數值,至關於針對數值的select count group by說明 返回結果的格式爲多行多列。 對於POST請求,把延時分爲10個桶,查看每一個桶的大小:method:POST | select numeric_histogram_u(10,latency)

數學統計函數

語句 含義 示例
corr(y, x) 給出兩列的相關度,結果從0到1。 latency>100| select corr(latency,request_size)
covar_pop(y, x) 計算整體協方差。 latency>100| select covar_pop(request_size,latency)
covar_samp(y, x) 計算樣本協方差。 latency>100| select covar_samp(request_size,latency)
regr_intercept(y, x) 返回輸入值的線性迴歸截距。 y是依賴值, x是獨立值。 latency>100| select regr_intercept(request_size,latency)
regr_slope(y,x) 返回輸入值的線性迴歸斜率。 y是依賴值, x是獨立值。 latency>100| select regr_slope(request_size,latency)
stddev(x)stddev_samp(x) 返回x列的樣本標準差。 latency>100| select stddev(latency)
stddev_pop(x) 返回x列的整體標準差。 latency>100| select stddev_pop(latency)
variance(x)var_samp(x) 計算x列的樣本方差。 latency>100| select variance(latency)
var_pop(x) 計算x列的整體方差。 latency>100| select variance(latency)

數學計算函數

支持的運算符號:+、-、*、/、%;能夠用在select句子中mysql

函數名 含義
abs(x) 返回x列的絕對值。
cbrt(x) 返回x列的立方根。
ceiling(x) 返回x列向上最接近的整數。
cosine_similarity(x,y) 返回稀疏向量x和y之間的餘弦類似度。
degrees 把弧度轉化爲度。
e() 返回天然常數。
exp(x) 返回天然常數的指數。
floor(x) 返回x向下最接近的整數。
from_base(string,radix) 以radix進制解釋string。
ln(x) 返回天然對數。
log2(x) 返回以2爲底,x的對數。
log10(x) 返回以10爲底,x的對數。
log(x,b) 返回以b爲底,x的對數。
pi() 返回π。
pow(x,b) 返回x的b次冪。
radians(x) 把度轉化成弧度。
rand() 返回隨機數。
random(0,n) 返回[0,n)隨機數。
round(x) x四捨五入。
round(x, y) 對x保留y個小數爲,例如round(1.012345,2) = 1.01。
sqrt(x) 返回x的平方根。
to_base(x, radix) 把x以radix進製表示。
truncate(x) 丟棄掉x的小數部分。
acos(x) 反餘弦。
asin(x) 反正弦。
atan(x) 反正切。
atan2(y,x) y/x的反正切。
cos(x) 餘弦。
sin(x) 正弦。
cosh(x) 雙曲餘弦。
tan(x) 正切。
tanh(x) 雙曲正切。
infinity() 返回正無窮的數值。
is_infinity(x) 判斷值是不是無限值。
is_finity(x) 判斷是不是有限值。
is_nan(x) 判斷是不是非數值。

字符串函數

函數名 含義
chr(x) 把int類型轉化成對應的ASCII碼,例如chr(65)結果爲A
codepoint (x) 把一個ASCII碼轉化成int類型的編碼,例如codepoint('A')結果爲65
length(x) 字段長度。
levenshtein_distance(string1, string2) 返回兩個字符串的最小編輯距離。
lower(string) 轉化成小寫。
lpad(string, size, padstring) string對齊到size大小,若是小於size,用padstring從左側補齊到;若是大於size則截取到size個。
rpad(string, size, padstring) 相似lpad,從右側補齊string
ltrim(string) 刪掉左側的空白字符。
replace(string, search) 把字符串中string中的search刪掉。
replace(string, search,rep) 把字符串中string中的search替換爲rep
reverse(string) 翻轉string。
rtrim(string) 刪掉字符串結尾的空白字符。
split(string,delimeter,limit) 把字符串分裂成array,最多取limit個值。生成的結果爲數組,下標從1開始。
split_part(string,delimeter,offset) 把字符串分裂成array,取第offset個字符串。生成的結果爲字符串。
split_to_map(string, entryDelimiter, keyValueDelimiter) → map string按照entryDelemiter分割成多個entry,每一個entry再按照keyValueDelimiter劃分紅key value。最終返回一個map。
position(substring IN string) 獲取string中,substring最早開始的位置。
strpos(string, substring) 查找字符串中的子串的開始位置。返回結果從1開始,若是不存在則返回0。
substr(string, start) 返回字符串的子串,start下標從1開始。
substr(string, start, length) 返回字符串的子串,start下標從1開始,length指定子串的長度。
trim(string) 刪掉字符串開頭和結尾的空白字符。
upper(string) 轉化爲大寫字符。
concat(string,string......) 把兩個或多個字符串拼接成一個字符串。
hamming_distance (string1,string2) 得到兩個字符串的海明距離。

日期和時間函數

函數類型

日期和時間函數主要是包含:android

  • 日期函數
  • 時間函數
  • 區間函數
  • 時序補全函數

日期時間類型

  1. 時間戳類型unixtime:以int類型表示從1970年1月1日開始的秒數,例如1512374067表示的時間是Mon Dec 4 15:54:27 CST 2017。日誌服務每條日誌中內置的時間__time__即爲這種類型。
  2. timestamp類型:以字符串形式表示,例如:2017-11-01 13:30:00

日期函數

函數名 含義 樣例
current_date 當天日期。 latency>100| select current_date
current_time 當前時間。 latency>100| select current_time
current_timestamp 結合current_date 和current_time的結果。 latency>100| select current_timestamp
current_timezone() 返回時區。 latency>100| select current_timezone()
from_iso8601_timestamp(string) 把iso8601時間轉化成帶時區的時間。 latency>100| select from_iso8601_timestamp(iso8601)
from_iso8601_date(string) 把iso8601轉化整天。 latency>100| select from_iso8601_date(iso8601)
from_unixtime(unixtime) 把unix時間轉化爲時間戳。 latency>100| select from_unixtime(1494985275)
from_unixtime(unixtime,string) 以string爲時區,把unixtime轉化成時間戳。 latency>100| select from_unixtime (1494985275,'Asia/Shanghai')
localtime 本地時間。 latency>100| select localtime
localtimestamp 本地時間戳。 latency>100| select localtimestamp
now() 等同於current_timestamp -
to_unixtime(timestamp) timestamp轉化成unixtime。 *| select to_unixtime('2017-05-17 09:45:00.848 Asia/Shanghai')

時間函數

  • date_format(timestamp, format)
  • date_parse(string, format)
函數名 含義 樣例
date_format(timestamp, format) 把timestamp轉化成以format形式表示。 latency>100
date_parse(string, format) 把string以format格式解析,轉化成timestamp。 latency>100

格式說明

格式 描述
%a 星期的縮寫,即Sun、Sat等。
%b 月份的縮寫,即Jan、Dec等。
%c 月份,數值類型,即1~12。
%D 每個月的第幾天,帶後綴,即0th、1st、2nd、3rd等。
%d 每個月第幾天,十進制格式,範圍爲01~31。
%e 每個月第幾天,十進制格式,範圍爲1~31。
%H 小時,24小時制。
%h 小時,12小時制。
%I 小時,12小時制。
%i 分鐘,數值類型,範圍爲00~59。
%j 每一年的第幾天,範圍爲001~366。
%k 小時,範圍爲0~23。
%l 小時,範圍爲1~12。
%M 月份的英文表達,範圍爲January~December。
%m 月份,數值格式,範圍爲01~12。
%p AM或PM。
%r 時間,12小時制,格式爲hh:mm:ss AM/PM
%S 秒,範圍爲00~59。
%s 秒,範圍爲00~59。
%T 時間,24時制,格式爲 hh:mm:ss
%V 每一年的第幾周,星期日是一週的第一天。範圍爲01~53,與%X同時使用。
%v 每一年的第幾周,星期一是一週的第一天。範圍爲01~53,與%x同時使用。
%W 星期幾的名稱,範圍爲Sunday到Saturday。
%w 一週的第幾天, 星期日爲第0天。
%Y 4 位數的年份。
%y 2位數的年份。
%% %轉義字符。

時間段對齊函數

按照秒、分鐘、小時、日、月、年等進行對齊ios

date_trunc(unit,x)
複製代碼
  • x是一個timestamp類型,也能夠是unix time
  • date_trunc只能按照固定時間間隔統計
*|select  date_trunc('minute' ,  __time__)  as t,
       truncate (avg(latency) ) ,
       current_date  
       group by   t
       order by t  desc 
       limit 60
複製代碼

時間間隔函數

時間間隔函數用來執行時間段相關的運算,如在日期中添加或減去指定的時間間隔、計算兩個日期之間的時間web

  • date_add(unit, value, timestamp):在timestamp的基礎上加上value個unit;若是value是負值,則進行減法
  • date_diff(unit, timestamp1, timestamp2):計算兩個timestamp之間差幾個unit
函數名 含義 樣例
date_add(unit, value, timestamp) timestamp上加上valueunit。若是要執行減法,value使用負值。 date_add('day', -7, '2018-08-09 00:00:00') 表示8月9號以前7天
date_diff(unit, timestamp1, timestamp2) 表示timestamp1timestamp2之間相差幾個unit date_diff('day', '2018-08-02 00:00:00', '2018-08-09 00:00:00') = 7

函數區間單位

單位 說明
millisecond 毫秒
second
minute 分鐘
hour 小時
day
week
month
quarter 季度,即三個月
year

時序補全函數time_series

時序補全函數time_series必須和group by time order by time一塊兒使用,且order by不支持desc排序方式sql

函數格式:json

time_series(time_column, window, format, padding_data)
複製代碼

參數說明:數組

參數 說明
time_column 時間列,例如日誌服務提供的默認時間字段__time__。格式爲long類型或timestamp類型。
window 窗口大小,由一個數字和單位組成。單位爲s(秒)、m(分)、H (小時)、或d(天)。例如2h、5m、3d。
format MySQL時間格式,表示最終輸出的格式。
padding_data 表示補全的內容,包括:0:補零。null:補null。last:補上一個值。next:補下一個值。avg:補先後的平均值。

URL函數

URL函數支持從標準URL路徑中提取字段,一個標準的URL以下:安全

[protocol:][//host[:port]][path][?query][#fragment]
複製代碼
函數名 含義 示例
輸入樣例 輸出結果
url_extract_fragment(url) 提取出URL中的fragment,結果爲varchar類型。 *| select url_extract_fragment('https://sls.console.aliyun.com/#/project/dashboard-demo/categoryList') 輸出結果爲/project/dashboard-demo/categoryList
url_extract_host(url) 提取出URL中的host,結果爲varchar類型。 *|select url_extract_host('http://www.aliyun.com/product/sls') 輸出結果爲www.aliyun.com
url_extract_parameter(url, name) 提取出URL中的query中name對應的參數值,結果爲varchar類型。 *|select url_extract_parameter('http://www.aliyun.com/product/sls?userid=testuser','userid') 輸出結果爲testuser
url_extract_path(url) 提取出URL中的path,結果爲varchar類型。 *|select url_extract_path('http://www.aliyun.com/product/sls?userid=testuser') 輸出結果爲/product/sls
url_extract_port(url) 提取出URL中的端口,結果爲bigint類型。 *|select url_extract_port('http://www.aliyun.com:80/product/sls?userid=testuser') 輸出結果爲80
url_extract_protocol(url) 提取出URL中的協議,結果爲varchar類型。 *|select url_extract_protocol('http://www.aliyun.com:80/product/sls?userid=testuser') 輸出結果爲http
url_extract_query(url) 提取出URL中的query,結果爲varchar類型。 *|select url_extract_query('http://www.aliyun.com:80/product/sls?userid=testuser') 輸出結果爲userid=testuser
url_encode(value) 對url進行轉義編碼。 *|select url_encode('http://www.aliyun.com:80/product/sls?userid=testuser') 輸出結果爲http%3a%2f%2fwww.aliyun.com%3a80%2fproduct%2fsls%3fuserid%3dtestuser
url_decode(value) 對url進行解碼。 *|select url_decode('http%3a%2f%2fwww.aliyun.com%3a80%2fproduct%2fsls%3fuserid%3dtestuser') 輸出結果爲http://www.aliyun.com:80/product/sls?userid=testuser

正則式函數

函數名 含義 樣例
regexp_extract_all(string, pattern) 返回字符串中命中正則式的全部子串,返回結果是一個字符串數組。 *| SELECT regexp_extract_all('5a 67b 890m', '\d+'),結果爲['5','67','890']*|SELECT regexp_extract_all('5a 67a 890m', '(\d+)a')結果爲['5a','67a']
regexp_extract_all(string, pattern, group) 返回字符串中命中正則式的第group個()內部分,返回結果是一個字符串數組。 *| SELECT regexp_extract_all(‘5a 67a 890m’, ‘(\d+)a’,1)結果爲[‘5’,’67’]
regexp_extract(string, pattern) 返回字符串命中的正則式的第一個子串 *|SELECT regexp_extract('5a 67b 890m', '\d+')結果爲'5'
regexp_extract(string, pattern,group) 返回字符串命中的正則式的第group個()內的第1個子串 *|SELECT regexp_extract('5a 67b 890m', '(\d+)([a-z]+)',2)結果爲'a'
regexp_like(string, pattern) 判斷字符串是否命中正則式,返回bool類型,正則式能夠只命中字符串的一部分。 *|SELECT regexp_like('5a 67b 890m', '\d+m')結果爲true
regexp_replace(string, pattern, replacement) 把字符串中命中正則式的部分替換成replacement。 *|SELECT regexp_replace('5a 67b 890m', '\d+','a')結果爲'aa ab am'
regexp_replace(string, pattern) 把字符串中命中正則式的部分刪除,至關於regexp_replace(string,patterm,'') *|SELECT regexp_replace('5a 67b 890m', '\d+')結果爲'a b m'
regexp_split(string, pattern) 使用正則式把字符串切分紅數組。 *|SELECT regexp_split('5a 67b 890m', '\d+')結果爲['a','b','m']

JSON函數

JSON主要有兩種結構:map和array。若是一個字符串解析成JSON失敗,那麼返回的是null。

  • json_parse(string):將字符串轉成JSON類型
  • json_format(json):將json類型轉成字符串
函數名 含義 樣例
json_parse(string) 把字符串轉化成JSON類型。 SELECT json_parse('[1, 2, 3]') 結果爲JSON類型數組
json_format(json) 把JSON類型轉化成字符串。 SELECT json_format(json_parse('[1, 2, 3]'))結果爲字符串
json_array_contains(json, value) 判斷一個JSON類型數值,或者一個字符串(內容是一個JSON數組)是否包含某個值。 SELECT json_array_contains(json_parse('[1, 2, 3]'), 2)或 SELECT json_array_contains('[1, 2, 3]', 2)
json_array_get(json_array, index) json_array_contains,是獲取一個JSON數組的某個下標對應的元素。 SELECT json_array_get('["a", "b", "c"]', 0)結果爲'a'
json_array_length(json) 返回JSON數組的大小。 SELECT json_array_length('[1, 2, 3]') 返回結果3
json_extract(json, json_path) 從一個JSON對象中提取值,JSON路徑的語法相似$.store.book[0].title,返回結果是一個JSON對象。 SELECT json_extract(json, '$.store.book');
json_extract_scalar(json, json_path) 相似json_extract,可是返回結果是字符串類型。 -
json_size(json,json_path) 獲取JSON對象或數組的大小。 SELECT json_size('[1, 2, 3]') 返回結果3

類型轉換函數

類型轉換函數用於在查詢中轉換指定值或指定列的數據類型。

函數格式

  • 在查詢中將某一列(字段)或某一個值轉換成指定類型。其中,若是某一個值轉換失敗,將終止整個查詢
cast([key|value] as type)
複製代碼
  • 在查詢中將某一列(字段)或某一個值轉換成指定類型。若是某一個值轉換失敗,該值返回NULL,並跳過該值繼續處理

參數

參數 說明
key 日誌的Key,表示將該字段全部的值都轉換成指定類型
value 常量值,表示將某個值轉換成指定類型

示例

  • 將數字123轉換爲字符串(varchar)格式:

    cast(123 AS varchar)
    複製代碼
  • 將uid字段轉換爲字符串(varchar)格式:

    cast(uid AS varchar)
    複製代碼

IP地理函數

IP 地理函數能夠識別一個 IP 是內網 IP仍是外網 IP,也能夠判斷 IP 所屬的國家、省份、城市

經常使用函數

函數名 含義 樣例
ip_to_domain(ip) 判斷 IP 所在的域,是內網仍是外網。返回 intranet 或 internet。 SELECT ip_to_domain(ip)
ip_to_country(ip) 判斷 IP 所在的國家。 SELECT ip_to_country(ip)
ip_to_province(ip) 判斷 IP 所在的省份。 SELECT ip_to_province(ip)
ip_to_city(ip) 判斷 IP 所在的城市。 SELECT ip_to_city(ip)
ip_to_geo(ip) 判斷 IP 所在的城市的經緯度,範圍結果格式爲緯度,經度 SELECT ip_to_geo(ip)
ip_to_city_geo(ip) 判斷 IP 所在的城市的經緯度,返回的是城市經緯度,每一個城市只有一個經緯度,範圍結果格式爲緯度,經度 SELECT ip_to_city_geo(ip)
ip_to_provider(ip) 獲取 IP 對應的網絡運營商。 SELECT ip_to_provider(ip)
ip_to_country(ip,'en') 判斷 IP 所在的國家,返回國家碼。 SELECT ip_to_country(ip,'en')
ip_to_country_code(ip) 判斷 IP 所在的國家,返回國家碼。 SELECT ip_to_country_code(ip)
ip_to_province(ip,'en') 判斷 IP 所在的省份,返回英文省名或者中文拼音。 SELECT ip_to_province(ip,'en')
ip_to_city(ip,'en') 判斷 IP 所在的城市,返回英文城市名或者中文拼音。 SELECT ip_to_city(ip,'en')

使用demo

  • 過濾掉內網請求,查看top10的網絡訪問省份
* | select count(1) as pv, ip_to_province(ip) as province   -- 判斷省份
where ip_to_domain(ip) != 'intranet'  -- 過濾內網
group by province  -- 分組
order by desc   -- 降序
limit 10  -- 取出前10個
複製代碼
  • 查看不一樣國家的平均響應延時、最大響應延時以及最大延時對應的 request

    select avg(latency), 
    	   max(latency),
    	   max_by(requestId, latency), 
    	   ip_to_country(ip) as country 
    group by country 
    limit 100
    複製代碼

地理函數

經常使用的地理函數包含:

  • geohash(string)
  • geohash(lat, lon)
函數名 含義 樣例
geohash(string) 將緯度、經度用geohash編碼,string爲字符串類型,內容是緯度、逗號、經度。 select geohash('34.1,120.6')= 'wwjcbrdnzs'
geohash(lat,lon) 將緯度、經度用geohash編碼,參數分別是緯度和經度。 select geohash(34.1,120.6)= 'wwjcbrdnzs'

Group by用法

GROUP BY 支持多列。GROUP BY支持經過SELECT的列的別名來表示對應的KEY

select avg(latency), projectName, date_trunc('hour', __time__) as hour   -- 取別名
group by ProjectName, hour
複製代碼

group by 支持grouping sets, cube, rollup

method:PostLogstoreLogs |select avg(latency)   group by cube(projectName,logstore)
method:PostLogstoreLogs |select avg(latency)   group by GROUPING SETS ( ( projectName,logstore), (projectName,method))
method:PostLogstoreLogs |select avg(latency)   group by rollup(projectName,logstore)
複製代碼

在group by中提取非agg列:若是使用了group by語法,那麼在select時,只能選擇select group by 的列原始內容,或者對任意列進行聚合計算,不容許獲取非group by列的內容

錯誤語法

*| select a,b, count(c),group by a   -- b行由多個可供選擇,系統不知道選擇哪一個
複製代碼

解決辦法:使用arbitrary函數

*| select a, arbitrary(b), count(c) group by a
複製代碼

窗口函數

窗口函數用處

在平常工做中,常常會遇到須要在每組內排名,好比下面的業務需求:

排名問題:每一個部門按業績來排名 topN問題:找出每一個部門排名前N的員工進行獎勵

面對這類需求,就須要使用sql的高級功能窗口函數了。

什麼是窗口函數

窗口函數,也叫OLAP函數(online anallytical processing,聯合分析處理)。窗口函數是用來跨行計算的。普通的SQL聚合函數是隻能用來處理計算一行內的結果,窗口函數能夠跨行計算,而且把結果填到每行中

基本語法

<窗口函數> over (partition by <用於分組的列名>
            order by <用於排序的列名>)
複製代碼

<窗口函數>的位置能夠放置兩種函數:

  1. 專用窗口函數:rank、dense_rank、row_number
  2. 聚合函數:sum、avg、count、max、min

由於窗口函數是對where或者group by子句處理後的結果進行操做,因此窗口函數原則上只能寫在select子句中

使用demo

select key1,key2,value
	rank() over (pratition by key2
                order by value desc) as rnk
from orders 
order by key1, rnk
複製代碼

函數

函數 含義
rank() 在窗口內,按照某一列排序,返回在窗口內的序號。
row_number() 返回在窗口內的行號。
first_value(x) 返回窗口內的第一個value,通常用法是窗口內數值排序,獲取最大值。
last_value(x) 含義和first value相反。
nth_value(x, offset) 窗口內的第offset個數。
lead(x,offset,defaut_value) 窗口內x列某行以後offset行的值,若是不存在該行,則取default_value。
lag(x,offset,defaut_value) 窗口內x列某行以前offset行的值,若是不存在該行,則取default_value。

demo-1

若是想對每一個班級內按照成績排名:

獲得以下結果

select *,
	rank() over (partition by 班級  -- rank()是排序的函數;同時對錶分組
                order by 成績 desc) as ranking   -- 對分組後的結果進行降序
from 班級表
複製代碼

關鍵字:

  • rank() over
  • partition by
  • order by

demo-2

  • 查詢在整個公司的人員中,獲取每一個人的薪水在部份內的排名
select department, personId, sallary, 
      rank() over (Partition by department
                  order by sallary desc) as sallary_rank
order by department, sallary_rank
複製代碼
  • 在整個公司的人員中,獲取每一個人的薪水在部門中的佔比
select department, personId, sallery * 1.0 / sum(sallery) over (partition by department) as sallary_percentage
複製代碼

having語法

having用於過濾group by以後的聚合計算結果,where是在聚合計算以前過濾原始數據

order by語法

對輸出結果進行排序

order by column [desc|asc]
複製代碼

實例demo

select avg(latency) as avg_latency, projectName 
group by projectName
having avg(latency) > 570000
order by avg_latency desc;
複製代碼

limit語法

用法

用於限制輸出結果的行數

limit N   -- 取前N行數據
limit S, N  -- 從S行開始,取出N行數據
複製代碼
  • 不支持將limit語法用於子查詢內部
  • 翻頁的offset不能超過1,000,000,即S+N必須小於1,000,000
  • N不能超過10,000

demo

  • 只獲取100行結果:

    * | select distinct(url) from log limit 100
    複製代碼
  • 獲取0行到第999行的結果,共計1000行:

    * | select distinct(url) from log limit 0,1000
    複製代碼
  • 獲取第1000行到第1999行的結果,共計1000行:

    * | select distinct(url) from log limit 1000,1000
    複製代碼

case when語法

case when語法對連續數據進行歸類,例如從http_user_agent中提取信息,歸類成Androidios兩種

select case 
when http_user_agent like '%android%' then 'andriod'   -- case的兩個判斷語法
when http_user_agent like '%ios%' then 'ios'
else 'unknown' end  -- else語句,end
as http_user_agent,
	count(1) as pv
	group by http_user_agent      
複製代碼

計算不一樣延時區間的分佈

select case
when latency < 10 then 's10'
when latency < 100 then 's100'
when latency < 1000 then 's1000'
when latency < 10000 then 's10000'
else 's_large' end
as latency_slot,
count(1) as pv
group by latency_slot
複製代碼

if語法

if語法邏輯上等同於case when語法

case 
	when condition then true_value
	[ else false_value]
end
複製代碼
  • if(condition, true_value)

若是conditiontrue,返回true_value,不然返回的是NULL

  • if(condition, true_value, false_value)

若是conditiontrue,返回true_value,不然返回的是false_value

coalesce語法

返回的是多個列的第一個非NULL值

coalesce(value1,value2,...)
複製代碼

nullif語法

若是value1value2相等,返回的是NULL;不然返回的是value1

nullif(value1,value2)    -- 若是value1和value2相等,返回的是NULL;不然返回的是value1
複製代碼

二進制字符串函數

二進制字符串類型varbinary有別於字符串類型varchar

  • || :鏈接函數,等同於concat函數
  • to/from_base64
  • to/from_base64url
語句 說明
鏈接函數 || a || b 結果爲ab
length(binary) → bigint 返回二進制的長度。
concat(binary1, …, binaryN) → varbinary 鏈接二進制字符串,等同於||。
to_base64(binary) → varchar 把二進制字符串轉換成base64。
from_base64(string) → varbinary 把base64轉換成二進制字符串。
to_base64url(binary) → varchar 轉化成url安全的base64。
from_base64url(string) → varbinary 從url安全的base64轉化成二進制字符串。
to_hex(binary) → varchar 把二進制字符串轉化成十六進制表示。
from_hex(string) → varbinary 從十六進制轉化成二進制。
to_big_endian_64(bigint) → varbinary 把數字轉化成大端表示的二進制。
from_big_endian_64(binary) → bigint 把大端表示的二進制字符串轉化成數字。
md5(binary) → varbinary 計算二進制字符串的md5。
sha1(binary) → varbinary 計算二進制字符串的sha1。
sha256(binary) → varbinary 計算二進制字符串的sha256 hash。
sha512(binary) → varbinary 計算二進制字符串的sha512。
xxhash64(binary) → varbinary 計算二進制字符串的xxhash64。

位運算

語句 說明 示例
bit_count(x, bits) → bigint 統計x的二進制表示中,1的個數。 SELECT bit_count(9, 64); — 2
SELECT bit_count(9, 8); — 2
SELECT bit_count(-7, 64); — 62
SELECT bit_count(-7, 8); — 6
bitwise_and(x, y) → bigint 以二進制的形式求x,y的and的值。 -
bitwise_not(x) → bigint 以二進制的形式求對x的全部位取反。 -
bitwise_or(x, y) → bigint 以二進制形式對x,y求or。 -
bitwise_xor(x, y) → bigint 以二進制形式對x,y求xor。 -

同比和環比函數

比和環比函數用於比較當前區間的計算結果和以前一個指定區間的結果

函數 含義 樣例
compare(value, time_window) 表示將當前時段計算出來的value值和time_window計算出來的結果進行比較。value爲double或long類型,time_window單位爲秒;返回值爲數組類型。返回值分別是當前值、time_window以前的值和當前值與以前值的比值。 *|select compare( pv , 86400) from (select count(1) as pv from log)
compare(value, time_window1, time_window2) 表示當前區間分別和time_window1和time_window2以前的區間值進行比較,結果爲json數組。其中,各個值的大小必須知足如下規則:[當前值,time_window1以前的值,time_window2以前的值,當前值/time_window1以前的值,當前值/time_window2以前的值]。 * | select compare(pv, 86400, 172800) from ( select count(1) as pv from log)
compare(value, time_window1, time_window2, time_window3) 表示當前區間分別和time_window1和time_window2,time_window3以前的區間值進行比較,結果爲json數組。其中,各個值的大小必須知足如下規則:[當前值,time_window1以前的值,time_window2以前的值,time_window3以前的值,當前值/time_window1以前的值,當前值/time_window2以前的值,當前值/time_window3以前的值]。 * | select compare(pv, 86400, 172800,604800) from ( select count(1) as pv from log)
ts_compare(value, time_window) 表示當前區間分別和time_window1time_window2以前的區間值進行比較,結果爲json數組。其中,各個值的大小必須遵循如下規則:[當前值,time_window1以前的值,當前值/time_window1以前的值,前一個時間起點的unix時間戳]。用於時序函數比較,須要在SQL中對時間列進行GROUP BY。 例如,* | select t, ts_compare(pv, 86400 ) as d from(select date_trunc('minute',__time__ ) as t, count(1) as pv from log group by t order by t ) group by t表示將當前時間段每分鐘的計算結果和上一個時間段每分鐘的計算結果進行比較。結果爲:d:[1251.0,1264.0, 0.9897151898734177, 1539843780.0,1539757380.0]t:2018-10-19 14:23:00.000

demo-1

計算當前1小時和昨天同一個時間段的PV比例

筆記:PV(PageView) 頁面點擊量,每次刷新就算一次瀏覽,屢次打開同一頁面會累加

開始時間爲2020-03-25 14:00:00;結束時間爲2020-03-25 15:00:00。

select compare(pv, 86400) from (select count(1) as pv from log)   -- 86400表示當前時間段減去86400秒
複製代碼

假設結果爲:

[9.0,19.0,0.47368421052631579]
複製代碼

其中:

  • 9:03-25的14:00:00到15:00:00的PV值
  • 19:03-24的14:00到03-25的14:00的PV值
  • 0.47368421052631579:表示當前時間段與以前時間段的比值

將數組展開成3列的寫法爲:

select diff[1], diff[2], diff[3] 
from select(compare(pv, 86400) as diff 
            from (select count(1) as pv 
                  from log))
複製代碼

比較函數和運算符

比較運算判斷參數的大小,能夠適用於任何可比類型,例如:int、bigint、double、text

比較運算符

當用比較運算符比較兩個值得時候,若是邏輯成立,則表示爲True,不然返回False

運算符 含義
< 小於
> 大於
<= 小於或等於
>= 大於或等於
= 等於
<> 不等於
!= 不等於

範圍運算符 BETWEEN

between用於判斷一個參數的值是否在另外兩個參數之間,範圍爲閉區間。

  • 若是邏輯成立,則返回true;不然返回false。

    示例:SELECT 3 BETWEEN 2 AND 6;邏輯成立,返回true。

    以上樣例等同於SELECT 3 >= 2 AND 3 <= 6;

  • BETWEEN能夠跟在not以後,用於相反邏輯的判斷。

    示例:SELECT 3 NOT BETWEEN 2 AND 6;,邏輯不成立,返回false。

    以上樣例等同於SELECT 3 < 2 OR 3 > 6;

  • 若是三個參數中任何一個包含Null,則返回的結果爲Null。

IS NULL 和 IS NOT NULL

用於判斷參數是否爲NULL

GREATEST 和 LEAST

用於獲取多列中的最大值或者最小值

select greatest(1,3,4)   -- 返回的是4
複製代碼

比較判斷:all、any、some

比較判斷用於判斷參數是否知足條件

  • all:用於判斷參數是否知足條件
  • any:用於判斷是否知足條件之一
  • some:判斷參數是否知足條件之一,同any的用法相同

三者必須緊跟在比較運算符以後

表達式 含義
A = ALL (…) A等於全部的值時,結果纔是true。
A <> ALL (…) A不等於全部的值時,結果纔是true。
A < ALL (…) A小於全部的值時,結果纔是true。
A = ANY (…) A等於任何一個值時,結果就爲true,等同於 A IN (…)。
A <> ANY (…) A不等於任何一個值時,結果爲true。
A < ANY (…) A小於其中最大值時,結果爲true。

看幾個例子

select 'hello' = any (values 'hello', 'world')    -- true,只要知足一個
select 21 < all (values 19,20,21)  -- false,須要所有知足
select 42 >= some(select 41 union all select 42 union all select 43);  -- true
複製代碼

Lambda表達式

lambda匿名函數的基本形式爲->

x -> x + 1
(x, y) -> x + y
x -> regexp_like(x, 'a+')
x -> x[1] / x[2]
x -> IF(x > 0, x, -x)
x -> COALESCE(x, 0)
x -> CAST(x AS JSON)
x -> x + TRY(1 / 0)
複製代碼

filter

基本格式:filter(array<T>, function<T,boolean) --->array<T>

select filter (array [], x -> true);   -- []
select filter (array [5, -6, null, 7], x -> x >0);  --[5,7]
select filter (array [5,null,7,null], x -> x is not null);  -- [5,7]
複製代碼

map_filter

map中過濾數據,只獲取知足function且返回true元素對

基本語法格式:map_filter(map<K, V>, function<K, V, boolean>) → MAP<K,V>

SELECT map_filter(MAP(ARRAY[], ARRAY[]), (k, v) -> true); -- {}
SELECT map_filter(MAP(ARRAY[10, 20, 30], ARRAY['a', NULL, 'c']), (k, v) -> v IS NOT NULL); -- {10 -> a, 30 -> c}
SELECT map_filter(MAP(ARRAY['k1', 'k2', 'k3'], ARRAY[20, 3, 15]), (k, v) -> v > 10); -- {k1 -> 20, k3 -> 15}
複製代碼

reduce

基本語法格式爲:reduce(array<T>, initialState S, inputFunction<S, T, S>, outputFunction<S, R>) → R

詳細步驟爲

  1. 初始狀態S
  2. 遍歷每一個元素T
  3. 計算inputFunction(S,T),生成新狀態S
  4. 重複步驟2~步驟3,直到最後一個元素被遍歷以及生成新狀態
  5. 利用最終狀態S,獲取最終輸出結果R
select reduce(array [], (s, x) -> s+x, s -> s);   -- 0
select reduce(array [5,20,50], (s, x) -> s+x, s -> s);   -- 75
select reduce(array [5,20,null,50], (s, x) -> s+x, s -> s);   -- null,任何數加上NULL都是NULL
select reduce(array [5,20,null,50], (s, x) -> s + coalesce(x,0), s -> s);  -- 75; coalesce返回的是多個列的第一個非NULL值
複製代碼

transform

基本語法:transform(array<T>, function<T, U>) → ARRAY<U>

對數組中的每一個元素,一次調用function,生成新的結果U

select transform(array [], x -> x+1);   --[]
select transform(array [5,6], x -> x+1);   -- [6,7]
select transform(array [5,null,6], x -> coalesce(x,0) + 1);  -- [6,1,7]
複製代碼

zip_with

基本語法格式:zip_with(array<T>, array<U>, function<T, U, R>) → array<R>

將兩個array合併,根據元素T、U,經過函數生成新的array中的元素R

SELECT zip_with(ARRAY[1, 3, 5], ARRAY['a', 'b', 'c'], (x, y) -> (y, x)); --調換先後兩個數組的元素位置,生成新的數組:[['a', 1], ['b', 3],['c', 5]]

SELECT zip_with(ARRAY[1, 2], ARRAY[3, 4], (x, y) -> x + y); -- 對應位置上的元素相加,結果[4, 6]

SELECT zip_with(ARRAY['a', 'b', 'c'], ARRAY['d', 'e', 'f'], (x, y) -> concat(x, y)); -- 把先後兩個數組的元素拼接,生成新的字符串:['ad', 'be', 'cf']
複製代碼

邏輯函數

運算符

運算符 描述 樣例
AND 只有左右運算數都是true時,結果才爲true a AND b
OR 左右運算數任一個爲true,結果爲true a OR b
NOT 右側運算數爲false時,結果才爲true NOT a

NULL參與邏輯運算符

重點標記的一種狀況

a b a AND b a OR b
TRUE TRUE TRUE TRUE
TRUE FALSE FALSE TRUE
TRUE NULL NULL TRUE
FALSE TRUE FALSE TRUE
FALSE FALSE FALSE FALSE
FALSE NULL FALSE NULL
NULL TRUE NULL TRUE
NULL FALSE FALSE NULL
NULL NULL NULL NULL

join

SQL中經常使用的4個join用法

  • inner join
  • left (outer) join
  • right (outer) join
  • full outer join

牢記此圖

牢記此圖

牢記此圖!

img

如下面的兩個表格爲例子:

mysql> SELECT * FROM Table_A ORDER BY PK ASC;
+----+---------+
| PK | Value   |
+----+---------+
|  1 | both ab |
|  2 | only a  |
+----+---------+
2 rows in set (0.00 sec)

mysql> SELECT * from Table_B ORDER BY PK ASC;
+----+---------+
| PK | Value   |
+----+---------+
|  1 | both ab |
|  3 | only b  |
+----+---------+
2 rows in set (0.00 sec)
複製代碼

inner join

內鏈接,將左右兩個表中可以關聯的數據鏈接起來,並返回出結果;PK爲公共字段

必需要有共同的字段!!!

SELECT A.PK AS A_PK, B.PK AS B_PK,
       A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
INNER JOIN Table_B B
ON A.PK = B.PK;
複製代碼

left (outer) join

左鏈接,返回左邊表的所有記錄,無論右表中有沒有關聯的數據。在右表中找到的關聯數據列一併返回

select A.PK as A_PK,B.PK as B_PK,   -- 字段取別名
       A.Value as A_Value, B.Value as B_Value
From Table_A A  -- 表取別名
left join Table_B B
on A.PK = B.PK;
複製代碼

right (outer) join

右鏈接,返回右邊表的所有記錄,無論左表中有沒有關聯的數據。在左表中找到的關聯數據列一併返回

select A.PK as A_PK,B.PK as B_PK,   -- 字段取別名
       A.Value as A_Value, B.Value as B_Value
From Table_A A  -- 表取別名
right join Table_B B
on A.PK = B.PK;
複製代碼

full (outer) join

常被稱做外鏈接,全鏈接。外鏈接查詢能返回左右表裏的全部記錄,其中左右表裏能關聯起來的記錄被鏈接後返回。

mysql中目前沒有full join功能

unnest語法

背景

在複雜的業務場景下,日誌數據的某一列可能會是較爲複雜的格式,例如數組(array)、對象(map)、JSON等格式。對這種特殊格式的日誌字段進行查詢分析,可使用unnest語法。

語法結構

unnest接收的是array或者map類型

若是輸入的是字符串類型,要先轉成json類型,再轉化成array類型或者map類型,轉化格式:

cast(json_parse(array_column) as array(biginit))
複製代碼
語法 說明
unnest( array) as table_alias(column_name) 表示把array類型展開成多行,行的名稱column_name
unnest(map) as table(key_name, value_name) 表示把map類型展開成多行,key的名稱爲key_name,value的名稱爲value_name

遍歷數組的每一個元素

  1. 展開數組
select array_column, a from log,  -- 展開每一個元素
unnest(cast(json_parse(array_column) as array(bigint))) as t(a)  -- 以t來命名新表,使用a來引用展開後的列
複製代碼
  1. 數組求和
select sum(a) from log,   -- 求和
unnest(cast(json_parse(array_column) as array(bigint))) as t(a)
複製代碼
  1. 利用 group by 進行分組
select a, count(1) from log,
unnest(cast(json_parse(array_num) as array(bigint))) as t(a)
group by a
複製代碼

遍歷map

  1. 遍歷map中的元素
select map_column,a,b from log,
unnest(cast(json_parse(map_column) as map(varchar, bigint))) as t(a,b)
複製代碼
  1. 按照map的key進行統計
select key, sum(value) from log,
unnest(cast(json_parse(map_column) as map(varchar, bigint))) as t(key, value)
group by key;
複製代碼

格式化顯示histogram,numeric_histogram

histogram

histogram函數相似於 count group by 語法,其結果一般是一連串的json數據

select key, value from (select histogram(method) as his from log),
unnest(his) as t(key,value)
複製代碼
numeric_histogram

numeric_histogram語法是將數值列分配到多個桶中去,至關因而對數值列進行group by

select key,value from (select numeric_histogram(10, Latency) as his from log),
unnest(his) as t(key,value)
複製代碼

電話號碼函數

電話號碼函數提供對中國內地區域電話號碼的歸屬地查詢功能

函數列表

  • mobile_province:省份
  • mobile_city:城市
  • mobile_carrier:運營商
函數名 含義 樣例
mobile_province 查看電話號碼所屬省份,須要傳入電話的數字形式。字符串參數可使用try_cast進行轉換。 * | select mobile_province(12345678)``* \| select mobile_province(try_cast('12345678' as bigint) )
mobile_city 查看電話號碼所屬城市,須要傳入電話的數字形式。字符串參數可使用try_cast進行轉換。 * | select mobile_city(12345678)``* \| select mobile_city(try_cast('12345678' as bigint) )
mobile_carrier 查看電話號碼所屬運營商,須要傳入電話的數字形式。字符串參數可使用try_cast進行轉換。 * | select mobile_carrier(12345678)``* \| select mobile_carrier(try_cast('12345678' as bigint) )

demo

select mobile_city(try_cast("mobile" as bigint)) as "城市",   -- try_cast將字符串轉成數值型
       mobile_province(try_cast("mobile" as bigint)) asd "省份",
       count(1) as "請求次數"
       group by "省份", "城市"
       order by "請求次數" desc 
       limit 1000
       )
複製代碼
相關文章
相關標籤/搜索