iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0
Software Development

Datomic,內建事件溯源的資料庫。系列 第 12

先從 Datalog 談起 -- part 7 (more join)

  • 分享至 

  • xImage
  •  

對 SQL 有點研究的讀者,應該多少知道 SQL 有許多種不同的 join。但是,要說 SQL 有 7 種不同的 join 方式的話,我覺得也有點太誇張了。首先,觀察下圖可以發現,left join 與 right join 有對稱性;left join ... is null 與 right join ... is null 也有對稱性,所以立刻可以刪去兩種 join 的方式。

SQL join

更進一步簡化的話,我們其實只需要三種語法,就足以湊出 7 種 join 的結果:

  1. inner join
  2. left join ... is null
  3. 合併多個查詢結果

利用 Datalog 來做出各種 SQL join

之前的文章,我們已經可以發現,一般的 Datalog 語法,就已經可以做出 inner join 。換言之,我們想要利用 Datalog 來做出各種 SQL join 的結果,只要找出對應 left join ... is null 以及合併多個查詢結果 (union) 的 Datalog 語法即可。

left join ... is null

假設我們要用 SQL 來查詢『那些在 person 表中存在,但是在 movie 表中沒有演出的演員』,可以寫成如下:

SELECT person.name
FROM person
LEFT JOIN movie
ON person.id = movie.cast
WHERE movie.cast IS NULL;

上述的寫法,我們可以先用另一種等價的 SQL 的寫法來加以改寫:

SELECT person.name
FROM person
WHERE NOT EXISTS (
    SELECT 1 
    FROM movie 
    WHERE movie.cast = person.id
);

而改成對應的 Datalog 的話,則可以利用 not 或是 not-join 子句(註1):

[:find ?name
 :where
 [?p :person/name ?name]
 (not [?m :movie/cast ?p])]

讀者有沒有覺得 SQL 與 Datalog 的寫法也長得有點像呢?仔細比較的話, Datalog 更有一致性喔。

union

假設我們要用 SQL 來查詢『所有人的名字與電影的名字之集合』,可以寫成如下:

SELECT name FROM person
UNION
SELECT title AS name FROM movie;

而改成對應的 Datalog 的話,則可以利用 or 或是 or-join 子句(註2):

[:find ?name
 :where
 (or
   [?p :person/name ?name]
   [?m :movie/title ?name])]

left join 的替代方案

如果讀者順著前面的邏輯思考,要湊出 left join 最直覺的作法,大概是如下:

  1. 先做出 inner join
  2. 設法做出 left join ... is null
  3. 把前兩個結果合併起來

但是,其實不用這麼麻煩,因為還有更偷懶的表現方式,比方說,利用 Datalog 的 pull 查詢。(註3)

以下方的這個例子來講,這個查詢是先找出所有的人,等有了人的資料實體編碼 (entity id) 之後,再用 pull 去看他們是否有被任何的電影找去當演員。

[:find [(pull ?e [:person/name 
                  :movie/_cast]) ...]
 :where 
 [?e :person/name]]

註:

  1. Datalog 查詢的語法 not clause
  2. Datalog 查詢的語法 or clause
  3. Datalog 不需要 left join 語法

其它資源

  1. 歡迎訂閱 PruningSuccess 電子報,主要談論軟體開發、資料處理、資料分析等議題。
  2. 歡迎加入 Clojure 社群

上一篇
先從 Datalog 談起 -- part 6 (more queries)
下一篇
先從 Datalog 談起 -- part 8 (predicates and transformation functions)
系列文
Datomic,內建事件溯源的資料庫。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言