Mysql

這個聲明具體是做什麼的?

  • September 2, 2021

該聲明

SELECT password 
FROM users 
WHERE username='' 
UNION 
SELECT 'test' 
FROM users

返回

password
--------
test

和聲明

SELECT username, password 
FROM users 
WHERE username='' 
UNION 
SELECT 'test', 'test' 
FROM users

返回

username        password
--------        --------
test            test

這裡到底發生了什麼?

因為如果您省略該WHERE子句,則第一個SELECT返回所有使用者行並UNION SELECT添加到該行test test

username        password
--------        --------
johnny          pw123
wiener          peter
test            test

我知道添加WHERE username=''子句不會返回任何行,因此UNION SELECT添加到任何包含test test.

但是當您只有語句SELECT 'test, 'test' FROM users時,它不會返回一個這樣的行,而是為每個使用者返回一行。所以多行。此語句的輸出中的行數與 users 表中的使用者數一樣多:

username        password
--------        --------
test            test          <- one for johnny
test            test          <- one for wiener

所以我試圖調和這些行為。SELECT上面通常會為每個使用者返回一行,但是當它添加UNION SELECT到 first 返回的SELECT行時,它只返回一行,而不是每個使用者一個。第一個SELECT不返回任何內容,除非該WHERE子句被省略,在這種情況下它返回所有使用者行。

作為這個長問題的UNION SELECT附加內容test test,例如

username        password
--------        --------
johnny          pw123
wiener          peter

所以很自然,它們屬於“使用者名”和“密碼”列。但是,當您有WHERE使第一個SELECT不返回任何內容的子句時,整個語句如何返回

password        username
--------        --------
test            test

並不是

Expr1000        Expr1000
--------        --------
test            test

是因為說SELECT返回“無”是不准確的,而是返回“在’使用者名’和’密碼’的列下沒有行”,這意味著它為UNION SELECT這些列建立,而不管第一SELECT列下是否有任何行他們?

我是否通過蘇格拉底的方法回答了我自己的問題?還是我的想法不對?如果我自己回答了,我很抱歉浪費你五分鐘的時間閱讀 400 字。

請注意,您應該始終將您使用的數據庫系統版本作為問題中的標籤之一,因為這通常是相關的。

我懷疑您在特定情況下遇到的問題(假設您的範例帶有測試數據)是MySQL中的UNION運算符發生的重複數據刪除:

預設情況下,從 UNION 結果中刪除重複的行。可選的 DISTINCT 關鍵字具有相同的效果,但使其顯式。使用可選的 ALL 關鍵字,不會刪除重複行,結果包括所有 SELECT 語句中的所有匹配行。

在您的第一個查詢中,該WHERE子句沒有匹配項,因此該語句的前半部分沒有要返回的行,但您的後半部分UNION是一個硬編碼值,該值對錶中的每一行重複但隨後進行了重複數據刪除由UNION操作員,最終導致單行。

正如您所注意到的,當您使用原始語句的後半部分直接查詢表時,您確實會得到一行,其中包含test為表中每一行重複的值。這是因為您不再使用UNION之前對結果進行重複數據刪除的運算符。

正如前面提到的 MySQL 文件引用中所指定的,如果您改用UNION ALL運算符,則不會刪除重複項,並且您將收到所有行,如預期的那樣,重複值為test. 例如SELECT password FROM users WHERE username='' UNION ALL SELECT 'test' FROM users

請注意,這也是大多數現代關係數據庫系統中該運算符的常見行為。

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