1. 程式人生 > 其它 >等值連線_sql高階教程:非等值自連線

等值連線_sql高階教程:非等值自連線

技術標籤:等值連線

問題介紹:

自連線的內部計算機制:

第一步:生成同一張表格的笛卡爾積。

有序數對:有序數對指的是<1,2>,無序數對指的是{1,2}。對於有序數對,兩組資料交換意義不同。即<1,2> 不等於<2,1>。而無序數對{1,2} = {2,1}。

3c04f2b61f0f39f0d297ad5ca31c2a3d.png
SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2;

執行結果裡每一行(記錄)都是一個有序對。因為是可重排列,所以結果行數為3^2 = 9。

04c44b7cd0160ea20ab74a9c91321813.png

結果裡出現了(蘋果, 蘋果)這種由相同元素構成的對和(橘子, 蘋果)和(蘋果, 橘子)這種只是調換了元素順序的對,這種對在有序數對中代表的意思不同。

第二步:排除相同元素構成的對(比如<蘋果,蘋果>這種對)

-- 用於獲取排列的SQL 語句

SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2
WHERE P1.name <> P2.name;

無論是p1還是p2,可以把這兩個表格當成兩個不同的表格,只是碰巧資料相同,相當於:

  • P1 裡的“蘋果”行的連線物件為P2 裡的“橘子、香蕉”這兩行
  • P1 裡的“橘子”行的連線物件為P2 裡的“蘋果、香蕉”這兩行
  • P1 裡的“香蕉”行的連線物件為P2 裡的“蘋果、橘子”這兩行

fce35802430d5da8aeafd5a0bc28db36.png

第三步:對相同元素構成的對去重(即只保留<蘋果,橘子>,<橘子,蘋果>對中的一個)

SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2
WHERE P1.name > P2.name;

52c40215493f4515af70ca01e6c11757.png

以上的結果是首先將字元按照首字母排序,可以發現結果是香蕉>蘋果>橘子,根據上文條件,橘子可以跟比它大的兩個字元結合,蘋果可以跟香蕉結合,而香蕉最大,則沒有可以匹配的資料。

第四步:將所有元素排成一行

-- 用於獲取組合的SQL 語句:擴充套件成3 列
SELECT P1.name AS name_1, P2.name AS name_2, P3.name AS name_3
FROM Products P1, Products P2, Products P3
WHERE P1.name > P2.name
AND P2.name > P3.name;

19497d392c9acb080f7082f02df6c35e.png

Leetcode習題:

180題:連續出現的數字

編寫一個 SQL 查詢,查詢所有Logs表中至少連續出現三次的數字。

5f4c0030c9c662245c8f4f50de61278d.png
Logs 表

79e347d0e09b473bf91c0706ee71e344.png
結果表
select distinct l1.Num as ConsecutiveNums
from Logs l1,Logs l2, Logs l3
where l1.Id = l2.Id-1 #合併規則,按照id+1來合併
and l2.Id = l3.Id-1
and l1.Num = l2.Num   #篩選規則
and l2.Num = l3.Num