一、基礎知識
(1)SQL LEFT JOIN 關鍵字
LEFT JOIN 關鍵字會從左表(table_name1)那裏返回所有的行,即使在右表(table_name2)中沒有匹配的行
語法:
SELECT column_name(s) FROM table_name1 LEFT JOIN table_name2 ON table_name1.column_name=table_name2.column_name
(2)SQL UNION 操作符
UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。
請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同。
語法:
SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2
二、實戰
(1)項目描述
現在有兩個表,一個是project(項目表)還有一個是user_project_record(用戶記錄表)表格。
用戶記錄表裏面存儲的是用戶已經看過的項目,項目表中存儲的是所有需要看的項目。
以下是項目表的字段
以下是用戶記錄表中的字段
顯示的頁面
(2)需求描述
首先在這個頁面需要展示的是用戶還沒有看過的項目的前四條包括計算機和英語。
(3)思路分析
從這個頁面可以看出,英語、計算機是項目的類型,所以通過項目的類型可以分出計算機和英語,接着,我查詢這個用戶的用戶記錄表,然後Not in 在項目表的,這樣就可以獲取這個用戶還沒有看過的項目了。但是用戶沒有看過的項目中有父級項目也有子級項目,所以應該同一級的進行比較,然後返回前四條。
(a)查詢項目的等級爲1項目類型爲0(計算機)的項目的id和優先級從t_project(表中)
SELECT id as parentId,priority as parentPriority FROM t_project WHERE project_level=1 and project_type=0
結果爲:
如果現在全部查出來呢?
(b) 查詢t_project表然後左連接剛纔查的項目的等級爲1和項目類型爲0的Id和優先級,然後條件爲 Parent_id = p2.parentId,這然查找的是
SELECT * FROM t_project p1
LEFT JOIN
(SELECT id as parentId,priority as parentPriority FROM t_project
WHERE project_level=1 and project_type=0) p2 on p1.parent_id=p2.parentId
WHERE project_level=2 AND project_type=0
(c)所以查詢所有的計算機項目的
(SELECT * FROM t_project p1
LEFT JOIN
(SELECT id as parentId,priority as parentPriority FROM t_project
WHERE project_level=1 and project_type=0) p2 on p1.parent_id=p2.parentId
WHERE project_level=2 AND project_type=0
AND id not in
(SELECT project_id
FROM t_user_project_record
WHERE user_id=1)
ORDER BY parentPriority,periodicity
LIMIT 4)
(d)再用UNION ALL 和英語進行連接
UNIONALL
(SELECT*FROMt_projectp3
LEFTJOIN
(SELECTidasparentId,priorityasparentPriorityFROMt_project
WHEREproject_level=1andproject_type=1)p4onp3.parent_id=p4.parentId
WHEREproject_level=2ANDproject_type=1
ANDidnotin
(SELECTproject_id
FROMt_user_project_record
WHEREuser_id=#{userId})
ORDERBYparentPriority,periodicity
LIMIT4)
三、最終答案
(SELECT * FROM t_project p1
LEFT JOIN
(SELECT id as parentId,priority as parentPriority FROM t_project
WHERE project_level=1 and project_type=0) p2 on p1.parent_id=p2.parentId
WHERE project_level=2 AND project_type=0
AND id not in
(SELECT project_id
FROM t_user_project_record
WHERE user_id=#{userId})
ORDER BY parentPriority,periodicity
LIMIT 4)
UNION ALL
(SELECT * FROM t_project p3
LEFT JOIN
(SELECT id as parentId,priority as parentPriority FROM t_project
WHERE project_level=1 and project_type=1) p4 on p3.parent_id=p4.parentId
WHERE project_level=2 AND project_type=1
AND id not in
(SELECT project_id
FROM t_user_project_record
WHERE user_id=#{userId})
ORDER BY parentPriority,periodicity
LIMIT 4)