//題目:
ID NAME
------------
1 張
1 王
2 趙
//結果:
ID NAME
--------
1 張
王
2 趙
//解法一:
with t as(
select 1 id, '張' name from dual union all
select 1 id, '王' name from dual union all
select 1 id, '李' name from dual union all
select 2 id, '趙' name from dual)
SELECT nullif(id, pid) id, NAME
FROM (
SELECT id, NAME,
lag(id) over(PARTITION BY id ORDER BY id) pid
FROM t)
ID NAME
---------- ----
1 張
王
李
2 趙
--
//分析:
//這裡巧妙的利用了lag()分析函數,
//此函數可一次性的返回多行資料,而不需要進行表的自串連
//而且可以將距離第一行記錄幾行的記錄返回,若沒有記錄就返回null
//下面是嵌套視圖的查詢結果:
SELECT id, NAME,
lag(id) over(PARTITION BY id ORDER BY id) pid
FROM t
/
ID NAME PID
---------- ---- ----------
1 張
1 王 1
1 李 1
2 趙
//我們再來看外層查詢,即主查詢
//這裡使用到了nullif()函數,本人還是頭一次看到此函數
//這個函數有兩個參數,nullif(x,y),
//它將x和y進行比較,如果x=y,則傳回值為null,如果不等,則返回x
For example:
NULLIF(12, 12) would return NULL
NULLIF(12, 13) would return 12
NULLIF('apples', 'apples') would return NULL
NULLIF('apples', 'oranges') would return 'apples'
//
//解法二:
with tt as(
select 1 id, '張' name from dual union all
select 1 id, '王' name from dual union all
select 1 id, '李' name from dual union all
select 2 id, '趙' name from dual)
select decode(row_number() over(partition by id order by id),1,id) id,
name
from tt
ID NAME
---------- ----
1 張
王
李
2 趙
//解析:
//此解法是用到了視窗函數row_number()分析函數,
//此函數是為每一個分組和排序返回一個排序值,用法有點像rownum
//我們來看看如果沒用decode函數結果是怎麼樣的:
select row_number() over(partition by id order by id) id,
name
from tt
ID NAME
---------- ----
1 張
2 王
3 李
1 趙
//使用decode函數是為了進行比較的,
//如果row_number函數返回的id值為1,那麼就顯示此id值
//如果row_number函數返回的id值不為1,那麼就顯示null
//所以我們看到了上面的結果:張的id為1,趙的id也為1