題解 | #篩選昵稱規(guī)則和試卷規(guī)則的作答記錄#
篩選昵稱規(guī)則和試卷規(guī)則的作答記錄
http://www.fangfengwang8.cn/practice/1c5075503ccf4de1882976b2fff2c072
# 找到昵稱滿足的,c開頭的試卷, # 計算按用戶和試卷分組的均分 SELECT uid, exam_id, ROUND(AVG(avg_score), 0) avg_score FROM ( # 設(shè)為子查詢是因為不能在這里對其分組 SELECT uid, exam_id, AVG(score) OVER(PARTITION BY uid, exam_id) avg_score FROM exam_record a JOIN user_info b USING(uid) JOIN examination_info c USING(exam_id) WHERE (nick_name LIKE '牛客%號' OR nick_name/2 > 0) AND (tag LIKE 'C%' OR tag LIKE 'c%')# WHERE LOWER(tag) LIKE 'c%' #使用該函數(shù)會更簡潔 ORDER BY uid, avg_score ) a GROUP BY uid, exam_id HAVING avg_score IS NOT NULL
踩的坑:限制條件這里,最開始沒有用圓括號,導致第一個or就使得第一個條件符合的就行了
在 SQL 中,AND
和 OR
是邏輯運算符,它們用來組合多個條件。AND
操作符表示所有條件都必須為真,才會選擇記錄;而 OR
操作符表示只要任一條件為真,就會選擇記錄。重要的是,AND
操作符的優(yōu)先級高于 OR
操作符。
讓我們來對比一下您給出的兩個 WHERE
子句:
有括號的條件:
WHERE (nick_name LIKE '???號' OR nick_name/2 > 0) AND (tag LIKE 'C%' OR tag LIKE 'c%')
- 這個查詢首先計算括號內(nèi)的條件,然后使用
AND
運算符組合結(jié)果。 - 只有當
nick_name
字段以 '牛客' 開頭并以 '號' 結(jié)尾或者nick_name/2
的結(jié)果大于 0,且同時tag
字段以大寫或小寫的 'C' 開頭時,記錄才會被選中。
沒有括號的條件:
WHERE nick_name LIKE '???號' OR nick_name/2 > 0 AND tag LIKE 'C%' OR tag LIKE 'c%'
- 在沒有括號的情況下,
AND
運算符將首先被計算。 - 所以
nick_name/2 > 0 AND tag LIKE 'C%'
會首先被評估,然后結(jié)果會與其他OR
條件組合。 - 這可能會導致不同的結(jié)果集,因為沒有明確的分組指示 SQL 如何組合這些條件。
為了更清楚地理解兩者之間的區(qū)別,讓我們分解第二個條件:
- 如果
nick_name
字段以 '??? 開頭并以 '號' 結(jié)尾,那么記錄會被選中,無論tag
字段的值是什么。 - 如果
nick_name/2
的結(jié)果大于 0 且tag
字段以大寫 'C' 開頭,那么記錄會被選中。 - 如果
tag
字段以小寫 'c' 開頭,那么記錄會被選中,無論nick_name
的值是什么。
可以看出,沒有使用括號的查詢可能會因為 OR
和 AND
的優(yōu)先級問題而返回更多的記錄。
通常來說,使用括號來明確指定條件的邏輯組合是一個好習慣,因為它可以避免混淆,并確保條件的執(zhí)行順序與你的意圖相符。
使用窗口函數(shù)時不需要 GROUP BY
:窗口函數(shù)會在保持原始行數(shù)不變的情況下為每行添加一個計算列。因此,如果您嘗試在窗口函數(shù)的查詢中同時使用 GROUP BY
,您可能會收到一個錯誤,因為 GROUP BY
會嘗試對結(jié)果集進行聚合。
新知識點:
1、在大多數(shù)SQL數(shù)據(jù)庫中,字符串比較默認是區(qū)分大小寫的。但是,你可以通過使用不區(qū)分大小寫的比較來簡化這個條件。根據(jù)你使用的數(shù)據(jù)庫系統(tǒng),有幾種方法可以實現(xiàn)不區(qū)分大小寫的搜索。
SQL標準方法
大多數(shù)數(shù)據(jù)庫都支持 ILIKE
關(guān)鍵字,或者 LOWER()
函數(shù)來進行不區(qū)分大小寫的比較:
使用 ILIKE
(這通常在 PostgreSQL 中可用):
WHERE tag ILIKE 'c%'
使用 LOWER()
函數(shù):
WHERE LOWER(tag) LIKE 'c%'
這兩種方法都會找到以 'C' 或 'c' 開頭的 tag
值。
MySQL
在 MySQL 中,你可以使用 COLLATE
來指定在比較時使用的字符集和校對規(guī)則,例如:
WHERE tag COLLATE utf8_general_ci LIKE 'c%'
這里 utf8_general_ci
是一個不區(qū)分大小寫的校對規(guī)則,ci 表示 case-insensitive(不區(qū)分大小寫)。
SQL Server
在 SQL Server 中,你需要查看列的校對順序設(shè)置。如果它被設(shè)置為不區(qū)分大小寫(例如 SQL_Latin1_General_CP1_CI_AS
),你可以直接使用:
WHERE tag LIKE 'c%'
并且它會返回所有以 'C' 或 'c' 開頭的 tag
值。
Oracle
在 Oracle 中,默認情況下字符串比較是區(qū)分大小寫的,但你可以使用 UPPER()
或 LOWER()
函數(shù)來進行不區(qū)分大小寫的比較:
WHERE LOWER(tag) LIKE 'c%'
在編寫你的查詢時,請根據(jù)你所使用的數(shù)據(jù)庫系統(tǒng)選擇適當?shù)姆椒?。如果你不確定數(shù)據(jù)庫的默認大小寫敏感性或者校對規(guī)則設(shè)置,使用 LOWER()
或 UPPER()
函數(shù)是一個可靠的選擇,因為它們在所有主流數(shù)據(jù)庫系統(tǒng)中都是可用的。
2、在 MySQL 中,要判斷一個字段的值是否為純數(shù)字,您不能直接使用 nick_name/2 > 0
,因為如果 nick_name
是一個包含非數(shù)字字符的字符串,這樣的除法操作會導致錯誤或者返回 NULL。
相反,您可以使用正則表達式來檢查一個字段是否只包含數(shù)字。在 MySQL 中,您可以使用 REGEXP
來進行正則匹配:
SELECT * FROM table_name WHERE column_name REGEXP '^[0-9]+$';
這條 SQL 語句會選擇 column_name
字段中只包含數(shù)字的所有記錄。這里的正則表達式 '^[0-9]+$'
的含義是:
^
:匹配字符串的開始[0-9]+
:匹配一個或多個數(shù)字$
:匹配字符串的結(jié)束
結(jié)合在一起,這個正則表達式匹配從開始到結(jié)束的整個字符串,確保字符串中沒有其他字符,只有數(shù)字。
在 MySQL 8.0+ 中,您也可以使用 RLIKE
,它是 REGEXP
的同義詞:
SELECT * FROM table_name WHERE column_name RLIKE '^[0-9]+$';
如果您使用的是早期版本的 MySQL,您可能需要使用不同的正則表達式語法或函數(shù)。請根據(jù)您的 MySQL 版本進行調(diào)整。