本文向您介紹SQL編碼的基本原則和詳細的編碼規範。
編碼原則
SQL代碼的編碼原則如下:
- 代碼功能完善,健壯。
- 代碼行清晰、整齊,具有一定的可觀賞性。
- 代碼編寫要充分考慮執行速度最優的原則。
- 代碼行整體層次分明、結構化強。
- 代碼中應有必要的註釋以增強代碼的可讀性。
- 規範要求非強制性約束代碼開發人員的代碼編寫行爲,在實際應用中在不違反常規要求的前提下允許存在可理解的偏差本規範在對日常的代碼開發工作起到指導作用的同時也將得到不斷的完善和補充。
- SQL代碼中應用到的所有關鍵字、保留字都使用小寫,如select、from、where、and、or、union、insert、delete、group、having、count等。
- SQL代碼中應用到的除關鍵字、保留字之外的代碼,也都使用小寫,如字段名、表別名等。
- 四個空格爲一個縮進量,所有的縮進皆爲一個縮進量的整數倍,按代碼層次對齊。 禁止使用select * 操作,所有操作必須明確指定列名。
- 對應的括號要求在同一列的位置上。
SQL編碼規範
SQL代碼的編碼規範如下:
- 代碼頭部
代碼頭部添加主題、功能描述、作者和日期等信息,並預留修改日誌及標題欄,以便後續修改同學添加修改記錄。注意每一行不超過80個字符。模板如下
-- MaxCompute(ODPS) SQL
--**************************************************************************
-- ** 所屬主題: 交易
-- ** 功能描述: 交易退款分析
-- ** 創建者 : 有碼
-- ** 創建日期: 20170616
-- ** 修改日誌:
-- ** 修改日期 修改人 修改內容
-- yyyymmdd name comment
-- 20170831 無碼 增加對biz_type=1234交易的判斷
--**************************************************************************
字段排列要求
- select語句選擇的字段按每行一個字段方式編排。
- select單字後面一個縮進量後直接跟首個選擇的字段,即字段離首起二個縮進量。
- 其它字段前導二個縮進量,再在逗號後放置字段名。
- 兩個字段之間的逗號分割符緊跟在第二個字段的前面。
- as語句應與相應的字段在同一行。多個字段的as建議儘量對齊在同一列上。
- INSERT子句排列要求
insert子句寫在同一行,請勿換行。 - SELECT子句排列要求
select語句中所用到的from、where、group by、having、order by、join、union等子句,需要遵循如下要求:
- 換行編寫。
- 與相應的select語句左對齊編排。
- 子句後續的代碼離子句首字母二個縮進量起編寫。
- where子句下的邏輯判斷符and、or等與where左對齊編排。
- 超過兩個縮進量長度的子句加一空格後編寫後續代碼,如order by、group by等。
- 運算符前後間隔要求算術運算符、邏輯運算符前後要保留一個空格,除非超過每行80個字符長度的限制,否則都寫在同一行。
- CASE語句的編寫
select語句中對字段值進行判斷取值的操作將用到的case語句,正確的編排case語句的寫法對加強代碼行的可閱讀性也是很關鍵的一部分。
對case語句編排作如下約定:
- when子語在case語句的同一行並縮進一個縮進量後開始編寫。
- 每個when子語一行編寫,當然如果語句較長可換行編排。
- case語句必須包含else子語,else子句與when子句對齊。
- 查詢嵌套編寫規範
子查詢嵌套在數據倉庫系統ETL開發中是經常要用到,因此代碼的分層編排就非常重要。示例如下:
- 表別名定義約定
- 所有的表都加上別名。因爲一旦在SELECT語句中給操作表定義了別名,在整個語句中對此表的引用都必須慣以別名替代。考慮到編寫代碼的方便性,約定別名儘量簡單、簡潔,同時避免使用關鍵字。
- 表別名採用簡單字符命名,建議按a、b、c、d……的順序進行命名。
- 多層次的嵌套子查詢別名之前要體現層次關係,SQL語句別名的命名,分層命名,從第一層次至第四層次,分別用P 、S、 U 、D表示,取意爲Part, Segment, Unit, Detail。也可用a、b、c、d來表示第一層次到第四層次;對於同一層次的多個子句,在字母后加1、2、3、4……區分。有需要的情況下對錶別名加註釋。
- SQL註釋
- 每條SQL語句均應添加註釋說明。
- 每條SQL語句的註釋單獨成行、放在語句前面。
- 字段註釋緊跟在字段後面。
- 應對不易理解的分支條件表達式加註釋。
- 對重要的計算應說明其功能。
- 過長的函數實現,應將其語句按實現的功能分段加以概括性說明。
- 常量及變量註釋時,應註釋被保存值的含義(必須),合法取值的範圍(可選)。
--**************************************************************************
-- step1 清理當天的數據分區
--**************************************************************************
代碼樣例
insert overwrite table dw_ckd_ocr_data
select coalesce(a.record_id,b.record_id) as record_id
,coalesce(a.type,b.type) as type
,coalesce(a.name,b.name) as name
,coalesce(a.createtime,b.createtime) as createtime
,coalesce(a.updatetime,b.updatetime) as updatetime
,a.`入院日期`
,a.`出院日期`
,a.`出院記錄/出院小結`
,b.`氯吡格雷用藥信息`
from (
select record_id
,type
,name
,to_char(updatetime, 'yyyy-mm-dd HH:MM') as updatetime
,to_char(createtime, 'yyyy-mm-dd HH:MM') as createtime
,WM_CONCAT(',',get_json_object(ocr_data,'$.data[0].入院日期')) as `入院日期`
,WM_CONCAT(',',get_json_object(ocr_data,'$.data[0].出院日期')) as `出院日期`
,WM_CONCAT('',get_json_object(ocr_data,'$.data[0].出院記錄/出院小結')) as `出院記錄/出院小結`
from ods_ocr_imgs
where name = '上傳出院小結'
and status=2
and uid in (
select trans_array(0,",",replace(replace(ocr_imgs,'[',''),']','')) as (ocr_imgs)
from ods_ocr_records
where project_id = '580f7eb5-7462-4755-80d9-70d25ac8be23'
and valid = true
and ocr_imgs != "[]"
)
group by record_id
,type,name
,status
,to_char(updatetime, 'yyyy-mm-dd HH:MM')
,to_char(createtime, 'yyyy-mm-dd HH:MM')
) a
full outer join (
select record_id
,type
,name
,to_char(updatetime, 'yyyy-mm-dd HH:MM') as updatetime
,to_char(createtime, 'yyyy-mm-dd HH:MM') as createtime
,get_json_object(ocr_data,'$.data[0].氯吡格雷用藥信息') as `氯吡格雷用藥信息`
from ods_ocr_imgs
where name = '上傳處方'
and status=2
and uid in (
select trans_array(0,",",replace(replace(ocr_imgs,'[',''),']','')) as (ocr_imgs)
from ods_ocr_records
where project_id = '580f7eb5-7462-4755-80d9-70d25ac8be23'
and valid = true
and ocr_imgs != "[]"
)
) b
on a.record_id=b.record_id;