上次寫了一篇復雜SQL編寫框架以及步驟,寫出一個復雜的SQL步驟,但是有一個東西沒有提及,那就是隱藏條件。隱藏條件在寫SQL的時候往往會忽略,最終導致結果可能是錯誤的。因此當我們在梳理表字段的時候一定要注意,如果拿不準可以問下表相關的業務同事幫你來確定。
一、看需求
上午需要給領導提供一份訂單權限學員詳情數據,就是學員買了課且有權限上課的詳情數據。具體需求如下:
uid;學員姓名;權限課程名稱;是否新學員(繳10000為新學員,否則為否) 學員省份(表單省/電話號碼所在省);學員城市(表單市/電話號碼所在市);訂單所在公司名稱;訂單企業所在省份;訂單企業所在城市;班級號;班級所在人數;
二、分析
如果按照復雜SQL的編寫框架來看,先梳理字段要用到的表,再梳理關聯關系和條件,最后就是寫出各個子查詢,把他們拼接在一起就可以了。我們可以看下這個需求的字段要用到的表:
-
user_right_course
uid;學員姓名;權限課程名稱;
-
order
是否新學員(繳10000為新學員,否則為否)
-
area
學員城市(表單市/電話號碼所在市);
訂單所在公司名稱;訂單企業所在省份;訂單企業所在城市;
-
class
班級號;
-
class_member
班級所在人數;
條件:
-
order.user_id=area.user_id -
order.order_no=user_right_course.order_no -
class.id=order.class_id
寫出SQL
SELECT
user_id,name,.......
CASE
WHEN order.real_fee = 10000 THEN '是'
ELSE '否'
END AS is_new_student,
FROM
user_right_course
LEFT JOIN
order ON order.order_no=user_right_course.order_no
LEFT JOIN
area on area.user_id=order.user_id
LEFT JOIN
class ON class.id=order.class_id
LEFT JOIN
(
SELECT
class_id,
COUNT(id) AS class_size
FROM
class_member
WHERE
delete_flag=0
GROUP BY
class_id
) m ON m.class_id=class.id
這樣就萬事大吉了嗎,不是的。
-
首先有的表有刪除標記delete_flag,那么在關聯的時候得帶上,我們只要沒刪除的(delete_flag=0)。 -
其次訂單表有刪除,退款,正常等狀態,我們只要正常的訂單(status=2)。 -
最后看user_right_course這個訂單權限表,它有status=0/1(0:無權限,1:有權限)。
那么這些隱藏條件也得加上去;
三、最終SQL
SELECT
user_id,name,.......
CASE
WHEN o.real_fee = 10000 THEN '是'
ELSE '否'
END AS is_new_student,
FROM
user_right_course
LEFT JOIN
(
SELECT
order_no
FROM
order
WHERE
status=2
) o ON o.order_no=user_right_course.order_no
LEFT JOIN
area on area.user_id=o.user_id
LEFT JOIN
class ON class.id=o.class_id
LEFT JOIN
(
SELECT
class_id,
COUNT(id) AS class_size
FROM
class_member
WHERE
delete_flag=0
GROUP BY
class_id
) m ON m.class_id=class.id
WHERE user_right_course.status=1 and user_right_course.delete_flag=0
四、總結
當然還有其他隱藏條件也需要去發現,比如班級有角色之分,我們這里只要學員,那么class表就不是單純的LEFT JOIN了,而得寫出子查詢,然后WHERE判斷role=學員。再就是有的條件需要深入到子查詢,比如course_id=10這門課程,只要涉及到的子查詢都應該將這個條件作為WHERE條件判斷。
這個過程需要持久的練習才能對隱藏條件更加敏感,所以寫的越多越容易能寫出復雜的SQL。