iT邦幫忙

2

SQL 子查詢 欄位where

目前的MySQL的查詢
(以下是我用比較簡單方式寫的範例 跟目前的SQL是一樣的寫法 只有欄位跟表格名稱不同)

select 
    A.name AS `name`,
    (select Bid from B JOIN C where B.cid=C.id AND A.id=B.aid AND B.id='1') AS `BID`
from A
where A.PID='A123456789' AND BID='A' 

這樣會說where 找不到BID這個欄位的 錯誤

另外前同事是寫

select *
from (
    select 
        A.name AS `name`,
        (select Bid from B JOIN C where B.cid=C.id AND A.id=B.aid AND B.id='1') AS `BID`
    from A
    A.PID='A123456789'
    ) oTable 
where BID='A'

這樣就可以

請問有其他效能比較好的改法嗎

2
小魚
iT邦大師 1 級 ‧ 2019-10-02 17:26:57
最佳解答
select 
    A.name AS `name`,
    B.Bid AS `BID`
from A
INNER JOIN B ON A.id=B.aid
INNER JOIN C ON B.cid=C.id
where A.PID='A123456789' AND B.Bid='A' AND B.id = '1'

這樣可以嗎?

看更多先前的回應...收起先前的回應...
柯柯 iT邦新手 5 級 ‧ 2019-10-02 17:42:30 檢舉

他的語法要改成JOIN要一段時間 明天上班再改看看
感謝~

小魚 iT邦大師 1 級 ‧ 2019-10-02 17:49:29 檢舉

話說回來,
我怎麼印象中MySql是可以直接查不用再包一層的呢?

player iT邦大師 1 級 ‧ 2019-10-02 22:16:41 檢舉

MySQL要4.1版以後才有支援子查詢。

小魚 iT邦大師 1 級 ‧ 2019-10-02 22:26:05 檢舉

所以這個版本是古董囉?
/images/emoticon/emoticon04.gif

1
Anthony_Yang
iT邦新手 4 級 ‧ 2019-10-02 17:30:59
select 
    A.name AS `name`,
    (select Bid from B JOIN C where B.cid=C.id AND A.id=B.aid AND B.id='1') AS `BID`
from A
where A.PID='A123456789' AND BID='A' 

子查詢查出來的欄位是Bid
盡管查出來後已經AS重新命名為BID
可是這時候Where條件辨識的還是舊的欄位名稱

select 
    A.name AS `name`,
    (select Bid AS `BID` from B JOIN C where B.cid=C.id AND A.id=B.aid AND B.id='1') 
from A
where A.PID='A123456789' AND BID='A' 

這樣應該就可以了

柯柯 iT邦新手 5 級 ‧ 2019-10-02 17:38:31 檢舉

這樣欄位名會變成(select Bid AS BID from B JOIN C where B.cid=C.id AND A.id=B.aid AND B.id='1') 所以也找不到

ted59438 iT邦新手 5 級 ‧ 2019-10-02 17:53:41 檢舉

---誤植請省略---

2
張小馬~
iT邦新手 3 級 ‧ 2019-10-02 17:33:18

效能要好:

  1. 子句不要寫在select裡
  2. 該join的資料先join好,再進行where。
  3. join的條件寫在on裡,不要寫在where裡。
  4. 語法越單純越好。
select A.name,B.Bid "BID"
from A
inner join B on A.id  = B.aid
inner join C on B.cid = C.id
where A.PID='A123456789' and B.id='1' and B.Bid = 'A'

此外你最前面的語法,因為該層你才令出BID這個東西,當然該層無法知道BID是什麼。就像是你說「我說的水果是葡萄」、「拿一串水果」,這是有先後順序的,同時發生的話,並不會知道要拿的水果是什麼水果。

看更多先前的回應...收起先前的回應...

哇靠我一看到提問就開始寫解答,竟然答完已經是第三個回答... XDD

柯柯 iT邦新手 5 級 ‧ 2019-10-02 17:42:38 檢舉

他的語法要改成JOIN要一段時間 明天上班再改看看
感謝~

小魚 iT邦大師 1 級 ‧ 2019-10-02 19:22:51 檢舉

我們兩個寫的語法好像是一樣的,
呵呵~

小魚,真的,搞得我像是抄答案的一樣。/images/emoticon/emoticon37.gif
這應該就叫做【英雄所見略同】吧~

小魚 iT邦大師 1 級 ‧ 2019-10-03 17:35:20 檢舉

我是不會這樣覺得啦,
畢竟時間很接近,
只是這樣子驗證語法正確的機率又更高了.
/images/emoticon/emoticon39.gif

1
ted59438
iT邦新手 5 級 ‧ 2019-10-02 17:36:59

野人獻曝 推一下最近在鐵人賽寫的文章:

第二堂:家事管理 - 認識查詢 (FROM→WHERE→SELECT→ORDER BY)
https://ithelp.ithome.com.tw/articles/10216972

因為SELECT 的執行順序在WHERE之後
FROM跟JOIN的執行順序在SELECT前面
所以跟樓上的大大們建議一樣
改放到FROM子查詢或JOIN,就可以在WHERE使用

另外可以參考這兩篇文章,理解SELECT子查詢跟FROM子查詢的差異:

  1. 第五堂:家事管理 - 每日家事分工一覽表 (SELECT 子查詢)
    https://ithelp.ithome.com.tw/articles/10218661

  2. 第六堂:家事管理 - 最後分工日期一覽表 (FROM 子查詢 + JOIN)
    https://ithelp.ithome.com.tw/articles/10219078

我要發表回答

立即登入回答