Postgresql

具有兩個 OR’ed 條件的 PostgreSQL WHERE 子句,優先級為第一

  • June 9, 2014

我在 PostgreSQL 中儲存使用者數據(使用者名、電子郵件、密碼雜湊),我只能在username. 我想讓使用者在登錄時提供他們的使用者名或電子郵件。但是,在將他們的輸入與使用者名和電子郵件地址進行匹配時,我想確保使用者名匹配優先於電子郵件匹配。

例如,在以下人為的實例中:

id | username        | email address    | pw_hash
-------------------------------------------------
1    john_doe          john@domain.com    x1j34
2    john@domain.com   john@domain.com    x1j34

如果兩個使用者都輸入了他們的使用者名,我想保證使用者 2 登錄。

如果我使用:

SELECT * FROM member WHERE (username='john@domain.com' OR email='john@domain.com') AND pw_hash='x1j34';

這匹配兩個使用者,但不保證訂單。

有沒有辦法必須條件,如果第一個條件不滿足,只檢查第二個條件?這可以在單個查詢中完成嗎?

在身份驗證期間,您需要檢查兩個條件:

  1. 有一個使用者名匹配;不需要通過電子郵件匹配。
  2. 沒有使用者名匹配的使用者;需要通過電子郵件匹配。

所以查詢是:

WITH matching_username AS (SELECT * FROM member WHERE username = 'john@domain.com')
SELECT * FROM matching_username WHERE (SELECT COUNT(*) FROM matching_username) = 1
                                  AND pw_hash = 'x1j34'
UNION 
SELECT * FROM member            WHERE (SELECT COUNT(*) FROM matching_username) = 0
                                  AND email = 'john@domain.com' 
                                  AND pw_hash='x1j34';

另一方面,您的表格設計存在問題。

如果兩個使用者有相同的電子郵件,但他們都沒有電子郵件作為他們的使用者名怎麼辦?如果其中一個人嘗試使用電子郵件進行身份驗證,您將無法判斷要針對哪個使用者記錄進行身份驗證。

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