1. 程式人生 > >TERADATA SQL學習隨筆<一>

TERADATA SQL學習隨筆<一>

此部落格內容簡介及目錄

最近在TERADATA環境學習SQL。在這裡記錄一下學習中查過的知識點,作為備案。

目錄:

  1. 關於SQL學習及所用線上資料庫
  2. 表聯合 (join)
  3. SQL子查詢
  4. 在select時建立新欄位 (as, case when)
  5. 資料分組 (group by + 聚合函式count, sum, avg等)
  6. 利用over (partition by)進行資料分組並建立新欄位
  7. 樣本選擇

1、關於SQL學習及所用線上資料庫

之前有看過一些SQL學習的書。但如果從學習效率來說,跟著書學習SQL,不如直接看生產環境的工作程式碼,遇到語句不懂時搜尋引擎查詢相應語句,效率會更高(例如本文就是此類的集中體現)。

當然,除了零星的知識點以外,網上還存在一些線上練習SQL取數的網站,在這裡列舉如下:

當然,我們也可以去下一些基礎練習資料庫,安裝mySql等進行練習。不過一般入門,學語法比學怎麼裝資料庫更重要。見仁見智吧。

另外,相比於簡單易懂的SQL語法學習,如何優化SQL語句效率,如何理解資料庫結構等等更加重要。這也是下一步我學習的重點。 具體參考這個連結 https://www.zhihu.com/question/20116482

那麼接下來,我選用oracle資料庫來練習最近查閱的知識點。

dept, emp。以下程式碼均以此為例項改寫。下圖為兩個表概覽

2、表聯合

select job,loc,dname from emp, dept where emp.deptno=dept.deptno

select job,loc,dname from emp join dept on dept.deptno = emp.deptno

 如上,上面兩個表都是用deptno聯合的,但一個是選擇了所有表,再篩選,另一個是做一個join

最常用的還是join

3、SQL的子查詢

select  loc, dname from
 (select job,loc,dname from emp 
        join dept on dept.deptno =
emp.deptno where loc = 'DALLAS' OR loc = 'New York' )

查詢套查詢,在實際工作環境中挺常見的。不是很難,就是用()把子查詢括起來。

可以把程式碼拷貝到如notepad++等程式碼編輯器裡,看到具體查詢巢狀關係,再一層一層反推取數邏輯。

4、在select裡建立新欄位

select建立新欄位,可以直接用...as 建立欄位

select ename, loc, 'DALLAS & NY' as city from emp 
        join dept on dept.deptno = emp.deptno
        where loc = 'DALLAS' OR loc = 'New York'

同理,也可以用case when建立有條件判斷的欄位,只需要加上括號即可。這個貌似還挺常見的

select ename, job, 
(case when sal >2000 then 'high'
                        when sal <1000 then 'low'
                        else 'middle'
                    End) as salary_level
    from emp

當然,case when還可以用於分組統計時建立欄位,與group by聯合使用。

---按job統計薪水大於1500的有多少人
select job, 
sum(case when sal >1500 then 1
                        
                        else 0
                    End) as salary_gt1500,
count(*) as people_vol
    from emp
    group by job

如要具體瞭解case when其他用法,還可再檢視以下博文:

5、資料分組並統計

一般資料分組用group by分組,基本與聚合函式配合使用。

原則是select後面的所有列,如果沒有用聚合函式,那麼必須在group by裡重寫一遍。

舉例如下面兩段程式碼,第一段會報錯

---錯誤:使用聚合函式count但沒有group by,或只group by一列
select mgr, job, count(*) as people_vol from emp
group by mgr
---正確:group by後引用完整列
select mgr, job, count(*) as people_vol from emp
group by mgr, job

6、利用over (partition by)分組並算相應值

之前的group by主要用於分組統計,而如sum, count等則是與group by組合輸出同組的一行資料。

如果我們要對每一行資料都輸出統計量,我們可以用over (partition by)進行分組並輸出。

這個可以用於:分組排序,或分組聚合等等。

舉例可看以下程式碼

---按job分組並給每個emp排序
select job, ename, sal,
row_number() over (Partition by job order by sal desc) as ranking
from emp
---分組並按job求各組平均值
select job, ename, sal,
avg(sal) over (Partition by job) as average_salary
from emp

具體用法,建議參閱以下部落格:

7、資料分組並篩選:where與having

用where進行資料篩選在SQL裡最常見。其工作環境中,主要巢狀子查詢、或者多條件(and or聯合)使用。注意結構就可以。

另外還有一種資料篩選是在分組以後進行,即group by .... having.... 之所以引用having,是因為where語句無法對聚合函式進行篩選

典型示例如下:

SELECT A COUNT(B) FROM TABLE GROUP BY A HAVING COUNT(B)>2

where 子句的作用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組之前過濾資料,條件中不能包含聚組函式,使用where條件顯示特定的行

having 子句的作用是篩選滿足條件的組,即在分組之後過濾資料條件中經常包含聚組函式,使用having 條件顯示特定的組,也可以使用多個分組標準進行分組。

我們可以用以下示例嘗試

---按mgr, job分組,並選出職工數>1的組 
---(由於select是sql執行最後一步,比group by晚執行。所以having裡不能直接用empl_vol)
select mgr, job, count(*) as empl_vol from emp group by mgr, job having count(*) > 1

8、資料分組並排序並篩選選出最近一批的資料

Group BY XXXX
HAVING
SUM(filteraaa) > 3 
QUALIFY RANK () OVER(PARTITION BY aa_ID ORDER BY MONTH_ID) =1;

Qualify rank 優化。報表執行順序,確保每一步過濾掉足夠多的資訊