Mysql

有人可以幫我理解這個查詢嗎

  • June 11, 2022

下面的 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 SmithAnna 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 的名稱

檢查小提琴

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