這幾天做軟體綜合設計的專案,我負責的是服務端,因為目前打算從前端轉型到後台,所以需要補足後台相關的知識。關於專案方面的東西就不介紹了,因為文章的主題是sql,直接給出資料表的設計圖。
表之間的連線線表示外來鍵。
以專案中的查詢為例,講述巢狀查詢語句以及表之間的連線。
1、獲取某一問題的所有回答(回答者、回答時間、回答內容)
分析:回答者username在user表,回答時間post_time在post表,回答內容content在answer表,將資料拆分到不同的表目的是為了減少冗餘,但是查詢起來就不方便了。這種情況下就要連線user、post、answer三張表。那怎麼連呢?post表中uid和aid是外來鍵,分別引用到user表和answer表,這就是我們連線三個表的橋梁。
解答:假設要查詢qid為9的問題的所有回答
select username, post_time, content
from user as u, post as p, answer as a
where u.uid = p.uid and p.aid = a.aid and a.qid = 9
這裡使用的是內連線(inner join),也稱為等值連線。
2、獲取使用者所提問題的資訊(提問時間、標題、內容、qid、回答數)
分析:提問時間ask_time在ask表,標題title和內容detail在question表,qid在question、ask和answer表都有,回答數需要用到count函式統計answer表中相同qid的行數。
這個查詢涉及到ask、question、answer三張表。麻煩的地方在於直接對answer表使用count函式只能統計出有回答的問題的回答數量,對於那些沒有回答的問題則無能為力。此時我們要使用外連線(outer join);內連線只顯示能夠連線上的行,而外連線能把連線不上的行也顯示出來。外連線的語法格式為:from table1 left outer join table2 on table1.id = table2.id。
上面的table2就是要連線的answer表,現在問題是table1怎麼來。
解答:
假設要查詢uid為9的使用者所提的所有問題的資訊。
步驟1:構造table1
select q.qid, q.title, q.detail, a.ask_time
from question as q, ask as a
where q.qid = a.qid and a.uid = 9
步驟2:
select t.ask_time, t.title, t.detail, t.qid, count(ans.aid) as answers
from table1 as t left outer join answer as ans
where t.qid = ans.qid
group by t.qid
將步驟1的查詢語句代入到步驟2中,得到巢狀的查詢語句:
select t.ask_time, t.title, t.detail, t.qid, count(ans.aid) as answers
from (
select q1.qid, q1.title, q1.detail, a.ask_time
from ask as a, question as q1
where a.qid = q1.qid and a.uid = $uid
) as t left outer join answer as ans
on t.qid = ans.qid
group by t.qid
這樣的查詢語句稱為包含子查詢的查詢語句。子查詢不僅能夠包含在from子句中,也還能包含在where子句中。
3、獲取附近問題的資訊(提問者,提問時間,經緯度,標題,內容,回答數)
分析:客戶端會將使用者的經度和緯度傳送過來,我要做的是篩選出以使用者為圓心的,半徑為3km範圍以內的問題。也就是說要在查詢語句中加上條件判斷。由於又涉及到問題的回答數,我們依然需要外連線answers表通過count(answers.aid)來計數。
步驟1:篩選出經度範圍為[115, 117],緯度範圍為[37, 40]內的問題
select * from question as q1
where 115 <= q1.longitude and q1.longitude <= 117
and 37 <= q1.latitude and q1.latitude <= 40
記為t1步驟2::連線answers表,統計問題的回答數
select t1.qid, t1.title, t1.detail, t1.longitude, t1.latitude, count(ans.aid) as answers
from t1 left outer join answers as ans
on t1.qid = ans.qid
group by t1.qid
記為t2步驟3:從user表和ask表中選出username和ask_time
select u.username, a.ask_time, t2.qid, t2.title, t2.detail, t2.longitude, t2.latitude, answers
from user as u, ask as a, t2
where u.uid = a.uid and a.qid = t2.qid
將以上查詢合併成一條查詢語句:
select u.username, a.ask_time, t2.qid, t2.title, t2.detail, t2.longitude, t2.latitude, answers
from user as u, ask as a,
( select t1.qid, t1.title, t1.detail, t1.longitude, t1.latitude, count(ans.aid) as answers
from (
select * from question as q1
where 115 <= q1.longitude and q1.longitude <= 117
and 37 <= q1.latitude and q1.latitude <= 40
)as t1 left outer join answer as ans
on t1.qid = ans.qid
group by t1.qid
) as t2
where u.uid = a.uid and a.qid = t2.qid;
sql語句的內連線外連線
假設一堆男女在教堂,有夫婦有單身的,假設男為左表,女為右表 教父說 結了婚的人請出去,結了婚的人請手拉手,於是結了婚的男女站了起來,這就是inner 內連 教父說 男的並且和這些男的結婚的女的請出去,結了婚的人請手拉手,於是,結了婚的夫婦手拉手出去,單身的男的也出去了。這就是 left 左連 教父說...
SQL查詢 內連線 外連線 自連線查詢
先建立2個表 學生表和教師表 在每個表中找出符合條件的共有記錄。x inner join y on.第一種寫法 只用where select t.teacher name,s.student name from teacher t,student s where t.id s.teacher id ...
SQL 內連線,外連線
假設一堆男女在教堂,有夫婦有單身的,假設男為左表,女為右表 教父說 結了婚的人請出去,結了婚的人請手拉手,於是結了婚的男女站了起來,這就是inner 內連 教父說 男的並且和這些男的結婚的女的請出去,結了婚的人請手拉手,於是,結了婚的夫婦手拉手出去,單身的男的也出去了。這就是 left 左連 教父說...