[筆記] SQL join/on/ROW_NUMBER
inner join
inner join 可以簡寫為 join
產生兩張表滿足 on 條件的記錄的交集
select
*
from
table_a
join
table_b
on
table_a.id = table_b.id
on 條件也可以是不等式
select * from table_a join table_b on table_a.id != table_b.id
不等於這種方式比較少用
left/right outer join
left/right outer join 可以簡寫為 left/right join
以 left join 為例子,左表必然出現在結果中,
對於右表存在滿足 on 條件的記錄的,取交集,和 inner join 一樣,
對於右表不存在滿足 on 條件的記錄的,取左表部分 + 補全 null
select
*
from
table_a
left join
table_b
on
table_a.id = table_b.id
right join 則相反
full outer join
full outer join 可以簡寫為 full join,
對於滿足 on 條件的記錄的,取交集,和 inner join 一樣,
對於右表不存在滿足 on 條件的記錄的,取左表部分 + 補全 null,和 left join 一樣,
對於左表不存在滿足 on 條件的記錄的,取右表部分 + 補全 null,和 right join 一樣
select
*
from
table_a
full join
table_b
on
table_a.id = table_b.id
相當於 left join 和 right join 的結合
cross join (或不指定 join 關鍵字)
把 table_a 和 table_b 的資料進行一個 N*M 的組合
select
*
from
table_a
cross join
table_b
或者
select
*
from
table_a, table_b
不需要加 on 條件,加上會報錯
on 條件用於過濾
on 條件除了做連結用,也可以做篩選用,
對於 inner join 過濾條件放在 on 還是 where 效果一樣,而 outer join 效果不一樣,
比如 left join 的左表有記錄 a 而右表有記錄 b 並且能滿足 on 條件,如果是在 where 過濾比如
where table_right.name != 'xxxx'
那麼 a 記錄和 b 記錄都不會出現在結果中,因為是先 join 再過濾,
而如果是在 on 過濾比如
on table_right.name != 'xxxx'
那麼 a 記錄依然出現在結果中,只是右表部分用 null 補全,因為先過濾掉 b 記錄再 left join
ROW_NUMBER
ROW_NUMBER() OVER(
[PARTITION BY column_1, column_2,…]
[ORDER BY column_3,column_4,…]
)
按欄位分組,然後組內排序,並按組內順序新增組內行號列
比如下面的 SQL
SELECT
group_id,
created_time,
Row_Number() OVER (partition by group_id ORDER BY created_time desc) row_id
FROM
table_a
資料按 group_id 分組,組內按 created_time 排序,組內排序後的行號作為新欄位 row_id 新增到記錄中
group_id | created_time | row_id
----------+---------------------+--------
group_1 | 2021-08-06 11:13:32 | 1
group_1 | 2021-08-06 11:12:32 | 2
group_1 | 2021-08-06 11:11:32 | 3
group_2 | 2021-08-06 12:13:32 | 1
group_2 | 2021-08-06 12:12:32 | 2
group_3 | 2021-08-06 13:13:32 | 1