有人可以幫我理解這個查詢嗎
下面的 SQL 查詢獲取所有具有不同姓氏的 id。
select * from names a WHERE a.first_name in ( select b.first_name from names b WHERE a.last_name<>b.last_name )
我無法弄清楚這到底是如何工作的。我認為會發生的是,對於表中的每一行,子查詢將檢查是否存在具有不同姓氏的行。但是檢查只發生在名字的相同值之間。有人可以解釋這實際上是如何工作的。
給出的 SQL 是相關子查詢的範例。
它是相關的,因為在子查詢中存在對外部表的引用。
有些人發現這種形式比編寫等效的 join 或 更直覺
EXISTS
。其他人覺得這有點奇怪,更難思考。SQL 通常允許我們以不同的方式編寫相同的邏輯查詢規範。給定一個好的優化器,你選擇哪一個歸結為風格問題。並不是所有的優化器都是好的。
在這種情況下,相關性是對 的引用
a.last_name
。這使得子查詢的結果依賴於外部查詢的“目前行”。從本質上講,查詢是詢問
first_name
屬性與屬性不同的任何行(來自同一個表)匹配的行last_name
。換句話說,共享名字但沒有姓氏的人。
您可以編寫與以下相同的要求:
SELECT * FROM names AS a WHERE EXISTS ( SELECT * FROM names AS b WHERE b.first_name = a.first_name AND b.last_name <> a.last_name );
IN
有些人可能會發現它比子查詢表單更容易閱讀。也許,它確實更容易看到涉及兩個測試。請參閱參考手冊中的13.2.11.7 相關子查詢。
下面的 SQL 查詢獲取所有具有不同姓氏的 id。
不,它沒有。
為什麼問題中的查詢不返回所有具有不同姓氏的名稱?
因為它不考慮相同的名稱。
簡單來說,在下面的範例中,哪些是具有不同姓氏的名稱?
回答。
John and Anna.
您正在選擇帶有 的行
first_name in (John,Anna)
,但在此條件下,將返回行John Smith
和Anna Smith
。按照下面的例子:
CREATE TABLE names ( `first_name` VARCHAR(15), `last_name` VARCHAR(15) ); INSERT INTO names VALUES ('John','Smith'), ('John','Test2'), ('Anna','Maria'), ('Anna','Smith'), ('Ron','Smith'), ('Maria','Smith');
基於問題中
SQL query gets all the ids which have different last names.
的查詢必須僅返回以下值,first_name last_name John Test2 Anna Maria
但它沒有,它給出:
first_name last_name John Smith John Test2 Anna Maria Anna Smith
為什麼返回錯誤的結果?
當您需要選擇具有不同姓氏的名稱時,您必須使用 last_names 計數等於 1 的條件。
也許您正在嘗試使用:
select * from names where last_name in ( select last_name from names group by last_name having count(*) = 1 )
這將只返回不共享 last_names 的名稱
檢查小提琴。