在實際應用中,對於具體的數據計算咱們會找相應的函數來實現。而計算需求不一樣的表達,每每會使得咱們使用不一樣的函數或方式來實現。或者也能夠說,同一計算可使用多種不一樣的表達方式實現。正則表達式
PostgreSQL 提供很是豐富的類型及函數,一些經常使用的函數可參考此文。sql
如下咱們經過實例來展現幾個經常使用的函數表達場景數組
首先,咱們建立示例數據以下函數
CREATE TABLE table_test ( id int PRIMARY KEY, test_name varchar(10), -- 名稱 group_code varchar(10), -- 組號 create_at timestamp, -- 建立時間 status bool, -- 狀態 test_desc varchar(100) -- 描述 ); -- 插入如下示例數據 INSERT INTO table_test (id, test_name, group_code, create_at, status, test_desc) VALUES (1, '一號', '01', now(), true, '評爲A'), (2, '一號', '01', now(), true, '評爲A'), (3, '二號', '02', now(), true, '評爲B'), (4, '三號', '01', now(), null, '評爲AC'), (5, '四號', '03', now(), true, '評爲C'), (6, '五號', '03', now(), true, '評爲AB');
當查詢條件中相關字段存在 NULL 值時,若是直接使用 WHERE 字段 = @參數值,則怎麼都匹配不了爲 NULL 值的記錄,由於NULL=任何值,包括 NULL=NULL 自己都不會返回 true,只會仍然是 NULL。ui
此時,能夠將 NULL 進行轉換,當字段值爲 NULL 時,轉換爲一個默認值。加密
使用 coalesce() 能夠表達此功能,它的功能是返回參數列表(支持不限定數量的參數)中,第一個非空值。spa
那若是咱們須要根據 status (包含 NULL 值,NULL時默認 false)來查詢,參數值多是 true/false,則能夠表達爲 coalesce(status, false),當 status 爲 NULL 時,天然返回的就是後邊的 false。.net
此時:coalesce(status, false) = (case when status is null then false else status end)code
-- status 中存在 NULL 值,如下參數可能爲 true/false SELECT * FROM table_test WHERE coalesce(status, false) = ?; SELECT * FROM table_test WHERE (case when status is null then false else status end) = ?;
(1)當前時間及時間格式化輸出blog
函數 now() 取得當前系統時間,等同於系統變量 CURRENT_TIMESTAMP
使用 to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS US') 能夠格式化時間,格式符含義以下:
YYYY 年,MM 月,DD 日,HH24 二十四小時制的時,MI 分,SS 秒, US 微秒
SELECT now(), CURRENT_TIMESTAMP, to_char(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS US') -- 輸入結果 "2019-04-21 23:24:45.276729+08" "2019-04-21 23:24:45.276729+08" "2019-04-21 23:24:45 276729"
(2)時間差
兩個時間相差的秒數使用:
extract(epoch FROM ( 時間1 - 時間2 ))
經過該函數,咱們能夠製做一個用於表示時間已過去多久的函數。
CREATE OR REPLACE FUNCTION public.f_time_span( t timestamp without time zone) RETURNS character varying LANGUAGE 'plpgsql' AS $$ DECLARE lv_span_double double precision; lv_span int8; BEGIN -- 取得當前時間與參數時間 相差的秒數 SELECT extract(epoch FROM (now() - t )) into lv_span_double; -- 轉換爲整型 lv_span := cast(lv_span_double as int8); IF lv_span < 11 THEN RETURN '幾秒前'; END IF; IF lv_span < 60 then RETURN lv_span || ' 秒前'; END IF; IF lv_span < 3600 THEN RETURN (lv_span / 60) || ' 分鐘前'; END IF; IF lv_span < 86400 THEN RETURN (lv_span / 3600) || ' 小時前'; END IF; IF lv_span < 30 * 86400 THEN RETURN (lv_span / 86400) || ' 天前'; END IF; IF lv_span < 365 * 86400 THEN RETURN (lv_span / (30*86400)) || ' 月前'; END IF; RETURN (lv_span / (365*86400)) || ' 年前'; END $$;
咱們應用於查詢中,如做爲建立時間隔如今多久的一個描述
SELECT test_name, create_at, f_time_span(create_at) span_desc FROM table_test
使用 UUID,須要安裝擴展 uuid-ossp,擴展安裝成功之後,就能夠經過 uuid_generate_v4() 或 uuid_generate_v1() 取得 UUID。
CREATE EXTENSION "uuid-ossp"; SELECT uuid_generate_v4() -- 輸出 "da28ce8a-ca9b-483f-918e-dce96fe7137f"
PostgreSQL 提供了除 SUM, COUNT, MAX, MIN, AVG 等以外更多的便捷的聚合函數。
string_agg(表達式, '分隔符') -- 按聚合的表達式值用分隔符鏈接成一串文本
array_agg(表達式) -- 將聚合的表達式值造成一個數組
如示例數據中,咱們但願返回每個組號內的名稱列表,則能夠:
SELECT GROUP_CODE, string_agg(test_name, ','), array_agg(test_name) FROM table_test GROUP BY GROUP_CODE
獲得結果以下圖
(1)MD5 加密
在用戶信息表中,密碼信息一般不明文存儲,有一種方式是使用密碼的 MD5 進行單向加密存儲從而保密性更強,PostgreSQL 想人之所想,提供了直接的 md5 函數,md5(text) 直接獲得 32 位的MD5 加密結果。
(2)正則相關
PostgreSQL 支持正則表達式,這爲查詢提供了極大的靈活性與表達空間。
語法格式爲:'字符串' ~ '正則表達式',含義相似 IsMatch('字符串' ,'正則表達式')
~* 則表示忽略大小寫,!~ 或 !~* 表示否認
也可使用 not '字符串' ~ '正則表達式' 表示否認
-- test_desc 包含 B 或 C 的 SELECT * FROM table_test WHERE test_desc ~ 'B|C'; -- test_desc 包含ABC中兩個字母相鄰的 SELECT * FROM table_test WHERE test_desc ~ '[A-C]{2}'; -- test_desc A結尾的 SELECT * FROM table_test WHERE test_desc ~ 'A$'; -- test_desc 不是A結尾的 SELECT * FROM table_test WHERE test_desc !~ 'A$';