Mysql

select語句列中的MYSQL子查詢

  • January 26, 2022

select(投影)的列欄位中的子查詢如何與主查詢的結果配對?形式:

SELECT id,email,(SELECT name From Names WHERE Names.id=Users.id) as name
FROM Users

子查詢是每行執行一次嗎SELECT id,email FROM UsersLIMIT 1從然後每個結果都與來自 的相應行配對SELECT id,email FROM Users,很像等價的連接:SELECT id,email,name FROM Users JOIN Names ON Users.id=Names.id

在理想情況下,當 Names.id = Users.id 只返回 1 條記錄時,兩個查詢相同

不正確時的區別。

SELECT id,email,(SELECT name From Names WHERE Names.id=Users.id) as name
FROM Users

將停止工作並返回錯誤,因此您需要添加 LIMIT 類

SELECT id,email,(SELECT name From Names WHERE Names.id=Users.id ORDER BY something LIMIT 1) as name
FROM Users

同時查詢

SELECT id,email,name FROM Users JOIN Names ON Users.id=Names.id

繼續工作而不會出現錯誤,此查詢返回與使用者相關的名稱中的所有行

在其他一些情況下,當您只期望 1 個名稱時,您需要添加 GROUP BY 條件

SELECT id,email,name FROM Users JOIN Names ON Users.id=Names.id GROUP BY Users.id

但是這種情況可能會從 Names 中返回不可預測的名稱(並且它不是 100% 的 SQL 合法構造),並且您需要再次添加 1 級 JOIN 與派生表,有時它可能是醜陋的構造,

因此,您始終可以比較哪種形式的查詢更適合所選案例,簡單範例:

SELECT t1.id,t1.email,t2.name FROM Users t1 JOIN 
(SELECT id, name FROM Names n1 INNER JOIN 
(SELECT MAX(dateregistered) as dateregistered, id FROM Names GROUP BY id) n2 ON n1.id=n2.id AND n1.dateregistered=n2.dateregistered) t2
ON t1.id = t2.id

將返回與以下相同的結果:

SELECT id,email,(SELECT name From Names WHERE Names.id=Users.id ORDER BY dateregistered DESC LIMIT 1) as name
FROM Users

**添加:**帶有名稱的範例看起來不現實,但真實情況 - 當您需要的不是名稱(實際上是每人 1 個),而是具有 10 年曆史的客戶的實際郵政地址。他可以有 20 個地址,並且你需要返回最重新發送

以我的經驗是的,您的子查詢將為您的外部查詢的每一行執行。

此外,由於您沒有在子查詢中使用任何形式的分組/聚合,因此無法保證該查詢將返回哪一行。

另一方面,查詢最好這樣寫:

SELECT u.id,u.email,n.name
FROM Users u
JOIN Names n
   ON n.id = u.id

正如下面所指出的,如果表使用者和表名稱不保持真正的一對一關係。使用者中的一行可能在名稱中具有相同 ID 的多行。如果是這種情況,您可以對查詢進行以下更改以解決此問題。

SELECT u.id,u.email,n.name
FROM Users u
RIGHT JOIN Names n
   ON n.id = u.id
WHERE u.id IS NOT NULL
LIMIT 1

這將為您生成使用者表中的每一行,它們在名稱表中擁有匹配的 id。但將響應限制為 1。請記住,如果沒有 LIMIT 1,這將列出重複的 u.email,如果出於某種原因,Names 表中的多個條目具有相同的 id。

引用自:https://dba.stackexchange.com/questions/168673