SQL的編碼顯得越來越重要,原因是很多邏輯處理,都可以跟sql掛鉤。 個人排斥將邏輯層代碼複雜化, 因此sql在未來的項目架構中,舉足輕重, 特地開一章節, 來總結一下以往項目中sql的精髓部分。
顯示某個店鋪的任務列表,同時把某個用戶的任務完成情況列出來。 傳入用戶的id_user值, 看看該用戶是否完成任務, 先前寫的sql如下:
<select id="listShopTask" parameterType="java.util.Map" resultMap="shopTaskResult">
SELECT
id_shop,
id_task,
is_online_task,
type_task,
freq,
url,
score,
descripe,
title,
time_start,
time_end
FROM shop_task t
WHERE t.id_shop = #{id_shop}
<if test="type_task != null ">
AND t.type_task =#{type_task}
</if>
order by time_start desc
<if test="beginIdx != null ">
LIMIT ${beginIdx}, ${length}
</if>
</select>
增加一個任務是否完成的屬性status_finish, 需記住:(Left Join是一個表,牢記這點就好):
SELECT
t.id_shop,
t.id_task,
t.is_online_task,
t.type_task,
t.freq,
t.url,
t.score,
t.descripe,
t.title,
t.time_start,
t.time_end,
uu.status_finish
FROM shop_task t
LEFT JOIN (SELECT
COUNT(1) AS status_finish,
mark, id_user,type_score, time_get
FROM score_user su
WHERE su.id_user='519006470'
GROUP BY su.mark) uu
ON t.id_task = uu.mark
WHERE t.id_shop = '50001020'
order by time_start desc
由於Left join 存在多個數量時, 返回內容過多,需要調整一下:
SELECT
t.id_shop,
t.id_task,
t.is_online_task,
t.type_task,
t.freq,
t.url,
t.score,
t.descripe,
t.title,
t.time_start,
t.time_end,
uu.time_get,
uu.id_user
FROM shop_task t
LEFT JOIN (SELECT
mark, id_user,type_score, time_get
FROM score_user su
WHERE su.id_user='340001477'
And type_score = 6
order by time_get desc) uu
ON t.id_task = uu.mark
WHERE t.id_shop = '50001020'
order by time_start desc
由於Left join 存在多個數量時, 返回內容過多,需要調整一下:
SELECT
t.id_shop,
t.id_task,
t.is_online_task,
t.type_task,
t.freq,
t.url,
t.score,
t.descripe,
t.title,
t.time_start,
t.time_end,
uu.time_get,
uu.id_user
FROM shop_task t
LEFT JOIN (SELECT
mark, id_user,type_score, time_get
FROM score_user su
WHERE su.id_user='519006470'
And type_score = 6
order by time_get desc
limit 0,1) uu
ON t.id_task = uu.mark
WHERE t.id_shop = '50001020'
order by time_start desc
limit將導致內容過少… ⊙﹏⊙b汗!
SELECT
mark, id_user,type_score, time_get
FROM score_user su
WHERE su.id_user='519006470'
And type_score = 6
order by time_get desc
OK終於可以搞定,Group是個很強大的語法。
SELECT
mark, id_user, type_score, MAX(time_get)
FROM score_user su
WHERE id_user='519006470'
AND type_score = 6
GROUP BY mark
結合以上,我們的結論是:
SELECT
t.id_shop,
t.id_task,
t.is_online_task,
t.type_task,
t.freq,
t.url,
t.score,
t.descripe,
t.title,
t.time_start,
t.time_end,
uu.last_time,
uu.id_user
FROM shop_task t
LEFT JOIN (SELECT
mark, id_user, type_score, MAX(time_get) AS last_time
FROM score_user su
WHERE id_user='519006470'
AND type_score = 6
GROUP BY mark) uu
ON t.id_task = uu.mark
WHERE t.id_shop = '50001020'
ORDER BY time_start DESC
總結:
1. Left Joion即增加一個表
2. 去掉笛卡爾常量的方法, 加限定詞: max, group by等