1、postgres中with用法的官方文檔地址
http://www.postgres.cn/docs/10/queries-with.html
2、有一張表biz_ticket,建表語句如下
CREATE TABLE "public"."biz_ticket" ( "id" int4 DEFAULT nextval('"crt".biz_ticket_id_seq'::regclass) NOT NULL, "create_time" timestamp(6), "type" text COLLATE "default" ) WITH (OIDS=FALSE) ; ALTER TABLE "public"."biz_ticket" OWNER TO "postgres"; COMMENT ON COLUMN "public"."biz_ticket"."id" IS '自增主鍵'; COMMENT ON COLUMN "public"."biz_ticket"."create_time" IS '創建時間'; COMMENT ON COLUMN "public"."biz_ticket"."type" IS '類型';
3、向表中插入10條數據
INSERT INTO "biz_ticket" VALUES (1, '2019-9-26 11:06:05', 'REQ'); INSERT INTO "biz_ticket" VALUES (2, '2019-9-26 11:06:50', 'BUG'); INSERT INTO "biz_ticket" VALUES (3, '2019-9-26 11:07:00', 'REQ'); INSERT INTO "biz_ticket" VALUES (4, '2019-9-26 11:07:17', 'OPPTY'); INSERT INTO "biz_ticket" VALUES (5, '2019-9-26 11:07:29', 'BUG'); INSERT INTO "biz_ticket" VALUES (6, '2019-9-26 11:07:58', 'BUG'); INSERT INTO "biz_ticket" VALUES (7, '2019-8-26 11:13:00', 'REQ'); INSERT INTO "biz_ticket" VALUES (8, '2018-9-26 11:13:22', 'REQ'); INSERT INTO "biz_ticket" VALUES (9, '2018-9-26 11:13:49', 'REQ'); INSERT INTO "biz_ticket" VALUES (10, '2019-8-26 11:16:00', 'BUG');
4、需求分析
計算9月份type=''REQ"的占比、同比和環比;
說明:
環比指的是相鄰兩月(即9月份和8月份)進行比較;
同比指的是歷史同期數據(即2019月9月與2018年9月)進行比較。
SQL語句如下:
WITH total_t AS ( -- 臨時表:獲取9月份數量總數量為:6條 SELECT COUNT (TYPE) AS tc FROM biz_ticket T WHERE -- 當前時間 T .create_time >= '2019-09-01 00:00:00' AND T .create_time <= '2019-09-30 23:59:59' ), type_zbc_t AS ( -- 臨時表:獲取9月份type='REQ'的數量為:2條 SELECT COUNT (TYPE) AS zbc FROM biz_ticket T WHERE -- 當前時間 T ."type" = 'REQ' AND T .create_time >= '2019-09-01 00:00:00' AND T .create_time <= '2019-09-30 23:59:59' ) , type_hbc_t as( -- 臨時表,獲取月環比(8月份)type='REQ'數量為:1條 SELECT COUNT (TYPE) AS hbc FROM biz_ticket T WHERE -- 環比時間 T ."type" = 'REQ' AND T .create_time >= '2019-08-01 00:00:00' AND T .create_time <= '2019-08-30 23:59:59' ), type_tbc_t as ( --臨時表,獲取去年同期(2018年9月type='REQ')同比數量為:2條 SELECT COUNT (TYPE) AS tbc FROM biz_ticket T WHERE -- 同比時間 T ."type" = 'REQ' AND T .create_time >= '2018-09-01 00:00:00' AND T .create_time <= '2018-09-30 23:59:59' ) SELECT case when t2.tc>0 then round(CAST (t1.zbc * 100.0 / t2.tc AS NUMERIC),2) else 0 end as zb, case when t3.hbc>0 then round(CAST (t1.zbc * 100.0 / t3.hbc AS NUMERIC),2) else 0 end as hb, case when t4.tbc>0 then round(CAST (t1.zbc * 100.0 / t4.tbc AS NUMERIC),2) else 0 end as tb FROM total_t t2, type_zbc_t t1, type_hbc_t t3,type_tbc_t t4;
結果展示:

5、重難點分析
5.1 WITH查詢(公共表表達式)
WITH提供了一種方式來書寫在一個大型查詢中使用的輔助語句。這些語句通常被稱為公共表表達式或CTE,它們可以被看成是定義只在一個查詢中存在的臨時表。在WITH子句中的每一個輔助語句可以是一個SELECT、INSERT、UPDATE或DELETE,並且WITH子句本身也可以被附加到一個主語句,主語句也可以是SELECT、INSERT、UPDATE或DELETE。
WITH中SELECT的基本價值是將復雜的查詢分解稱為簡單的部分。
5.2 CASE WHEN...THEN...ELSE...EDN
詳情請參考官方文檔:http://www.postgres.cn/docs/10/functions-conditional.html#FUNCTIONS-CASE
CASE表達式是一種通用的條件表達式,類似於其它編程語言中的 if/else 語句:

CASE子句可以用於任何表達式可以出現的地方。每一個condition是一個返回boolean結果的表達式。如果結果為真,那么CASE表達式的結果就是符合條件的result,並且剩下的CASE表達式不會被處理。如果條件的結果不為真,那么以相同方式搜尋任何隨后的WHEN子句。如果沒有WHEN condition為真,那么CASE表達式的值就是在ELSE子句里的result。如果省略了ELSE子句而且沒有條件為真,結果為空。
5.3 ROUND

5.4 CAST
CAST函數用於類型轉換:
CAST(aa as NUMERIC)
CAST( bb as VARCHAR)
轉載:https://blog.csdn.net/qq_34721505/article/details/101428948
