- select所查詢的結果是放在一個結果集裏面的,相當於又建了一張表,把結果放進結果表裏面。
- SQL是不區分大小寫的。
- 一個主鍵可能由一個表的一列或多列構成。
- 兩個連續的單引號表示字符串裏面的一個單引號字符。例如,輸入’don’’t’表示don’t。
- 保持字符列儘可能短要勝過爲他們留下“增長空間”。短列的排序和分組要比長列快一些。
- SQL的select語法:select column from tables
[join joins]
[where search_condition]
[group by group_columns]
[having search_condition]
[order by sort_columns];
- 使用SELECT *經常是有風險的,因爲表中列的個數或順序一旦更改就有可能引起程序執行失敗。同樣地,SELECT*將無法被不熟悉表中列的人所理解。與在SELECT字句中給出特定列名的查詢相比,SELECT*被跨越網絡傳遞不需要的數據拖住,佔用大量資源。
所以使用SELECT*的缺點如下:
①SELECT * 語句取出表中的所有字段,不論該字段的數據對調用的應用程序是否有用,這會對服務器資源造成浪費,甚至會對服務器的性能產生一定的影響。
②如果表的結構在以後發生了改變,那麼SELECT * 語句可能會取到不正確的數據甚至是出錯。
③執行SELECT * 語句時,SQL Server首先要查找出表中有哪些列,然後才能開始執行SELECT * 語句,這在某些情況會產生性能問題。
④使用SELECT * 語句將不會使用到覆蓋索引,不利於查詢的性能優化。
⑤在文檔角度來看,SELECT * 語句沒有列明將要取出哪些字段進行操作,所以也是不推薦的。
- 創建列的別名:
Select column1 [AS] alias1,
Column2 [AS] alias2,
......
columnN [AS] aliasN
From table;
- 如果表有被正確定義的主鍵,那麼因爲所有的行都是唯一的,所以SELECT DISTINCT * FROM TABLE;和SELECT * FROM TABLE;將返回相同的結果。
- SQL允許在Order by中指定列的相對位置編號而不是列名。位置編號引用的是結果中的列,而不是原始表中的列。
Select columns from table order by
sort_num1[ASC|DESC],
sort_num2[ASC|DESC],
sort_num3[ASC|DESC],
.....
sort_numN[ASC|DESC];
列如:select name,age from authors order 4 ASC,2 DESC;
假設結果集中有 phone,city,name,age這4列,那麼結果就是對age升序,city降序排列。
- 最影響排序的速度,按照重要程度排序如下:
①選擇的行的數量
②order by子句中列的數量
③order by子句中列的長度(指的是列的數據類型長度)
- 可以使用別名進行排序。
- 在SQL中<>表示不等於,類似於!=。
- 最好的習慣是隻將簡單的列引用放在=的左邊,而將更加複雜的表達式放在=的右邊。
- 一般而言,最快的比較是相等(=),然後是不相等(<,<=,>,>=),最慢的是不相等(<>)。
- 如果在select子句中給列定義了別名,那麼不能在where子句中引用它。
- Not表示否定(取反)一個條件,select ..... where Not(age<20);表示查詢年齡不小於20的信息。
- And比or有更高的優先級。
- 如果查詢條件只包含and操作符,首先放置爲真可能性最小的條件,查詢將會變快。如果,col1 = ‘A’的可能性比col2 = ‘B’比小,那麼 where col1 = ‘A’and col2 = ‘B’比where col2 = ‘B’ and col1 = ‘A’快,因爲如果以一個爲假,則DBMS()就不去計算第二個表達式了。對於只包含or操作符的查詢條件,則按相反的方式操作。
- 分配律:
條件 |
等價於 |
NOT(NOT p) |
p |
NOT(p AND q) |
(NOT p) or (NOT q) |
NOT(p OR q) |
(NOT p) AND (NOT q) |
P AND (q OR r) |
(P AND q) OR (P AND r) |
P OR (q AND r) |
(p OR q) AND(p OR r) |
- LIKE只對字符串起作用,對日期和數字不起作用。
可以看出通配符是用“!”表示的,並且要放在轉義的符號前面。
- 通配符查找是很耗時間的------特別是如果使用以%開頭的模式。
- Between和and是包含兩端的值的。
- SQL提供了IS NULL來確定給定的值是否爲空值。IS NULL可以應用於任意數據類型的列。
- 空值和空串的區別:空值是沒有輸入的,空串是有輸入的。其中空值插入的時候,只能insert tablename(column) values(NULL);
- 算數操作符(+、-、*等)的優先級高於比較操作符(<,=,>等),比較操作符的優先級高於邏輯操作符(NOT、AND、OR)。
- 對於複雜的表達式添加圓括號(即便他們是不必要的)以確保期望的計算順序,是代碼更具可移植性和易懂性,這是一種良好的編程風格。
- 使用||連接串:string1||string2。
可以在SELECT、where和ORDER BY子句中或者任何允許使用表達式的位置使用||。
在mysql中是用CONCAT(str1,str2,...)來連接。
- CAST:把一種類型轉換成另外一種類型。CAST(EXPR AS TYPE)。將INT(a)轉換成CHAR:CAST(a AS CHAR(10))。
- SUBSTRING函數SUBSTRING(str FROM pos FOR len);str是從中提取字串的源串(包含字符串的列、串字面量或者是返回串的運算或函數的結果),pos 是截取開始位置(從1開始),len是要截取這個字符串的長度,如果省略for length,那麼就表示從開始位置截取到末尾。
- TRIM()去空格:TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str)。Str是串表達式,LEADING 刪除前面的空格,TRAILING刪除後面的空格,BOTH同時刪除前面和後面的空格。如果不指定,默認爲BOTH。
- 使用character_length得到字符串長度:CHARACTER_LENGTH(STR)。
- 使用POSITION查找字串:POSITION(substring in string)。Substring是要查找的串,string是被查找的串。
- 函數EXTRACT()將日期或時間間隔隔離爲單一的字段,並以數字形式返回。
輸入:EXTRACT(field FROM datetime_or_interval)。Field是Year、Month、Day、HOUR、MINUTE、SECOND、TIMEZONE_HOUR或TIMEZONE_MINUTE。
- CURRENT_DATE返回DATE,CUREENT_TIME返回TIME,CURRENT_TIMESTAMP返回TIMESTAMP.
- CASE用法:CASE comparison_value
When value1 THEN result1
When value2 THEN result2
...
When valueN THEN resultN
[else default_result]
END;
Value1,value2...valueN是表達式。Result1,result2...resultN是在相應的值與表達式comparison_value相匹配時返回的表達式。如果省略else default_result,默認 else null。
- 輸入CASE
WHEN condition1 then result1
When condition2 then result2
...
When conditionN then resultN
【else default_result】
END;
Condition1,condition2...conditionN是搜索表達式(搜索條件是一個或者多個表達式,而它又是以and或or連接的複合表達式組成的)。Result1,result2...resultN是當相應的條件值爲真時返回的表達式。所有的表達式必須是一個類型或者隱式的轉換爲一個類型。
- COALESCE檢查空值:coalesce(expr1,expr2,expr3);類似於:
Case when expr1 is not null then expr1,
When expr2 is not null then expr2,
Else expr3;
- 函數NULLIF比較兩個表達式,如果他們相等則返回空值,如果不相等則返回第一個表達式。NULLIF(expr1,expr2)等價於
Case when expr1 = expr2 THEN NULL
Else expr END;
SUM()和AVG()只對數字數據類型起作用。MIN()和MAX()對字符,數字、日期和時間數據類型起作用。COUNT(EXPR)和COUNT(*)對所有數據類型起作用。
注意:
①聚合函數不能出現在where表達式裏面。
②select字句必須全部包含非聚合表達式,或者全部包含聚合表達式。(對於有分組的情況除外)。
③可以在SELECT子句中使用多個聚合表達式。
④不可以嵌套聚合函數。(ORACLE可以在GROUP BY查詢中嵌套聚合函數)
⑤可以在子查詢中使用聚合表達式。
⑥不可以在聚合表達式中使用子查詢。
- 在count(expr)中不統計空值的情況。
- 可以用GROUP BY子句將一個表分隔成邏輯組(類別),並且對每一組進行聚合統計量。
GROUP BY子句主要特點如下:
①GROUP BY子句唯一where之後和ORDER by子句之前。
②分組可以是列名或者派生列。
③輸入表中的列無法出現在聚合查詢的SELECT子句中,除非他們也被包含在GROUP BY中。也就是說聚合函數和單獨的列不能同時出現在SELECT句子中,除非有GROUP BY 包含單獨的列。列如:select pub_id(單獨的列),title_id,COUNT(*)(聚合函數)from titles group by pub_id,title_id(必須出現group by否則出錯,並且group by要把這兩列全部列進來);
④如果SELECT子句包含複雜的非聚合表達式,那麼GROUP BY表達式必須準確的匹配SELECT表達式。
⑤可以在GROUP BY子句中指定多個分組列來嵌套分組。
⑥如果分組列包含一個空值,在結果中這行會變爲一個分組。如果分組列包含多個空值,空值將被放進一個分組中。
⑦可以在包含GROUP BY子句的查詢中使用WHERE子句,在分組前消除行。
⑧儘管表的別名被允許作爲標識符,但不能在GROUP BY子句中是用列的別名。
- HAVING子句的主要特點如下:
①HAVING子句位於GROUP BY子句之後,ORDER BY子句之前。
②HAVING限制了GROUP BY的行數。
③WHERE查詢條件在分組產生以前就被應用,而HAVING是在分組之後。
④除了HAVing可以包含聚合函數之外,HAVING語法與where類似。
⑤HAVING子句可以引用顯示在select列表中任意一項。
總結:其實HAVING的作用同where一樣,增加了限制條件。
- 別名隱藏了表名。如果爲表命名了別名,則必須在所有的限定引用中使用它的別名。
- JOIN和WHERE可以等價查詢。
- 在三表聯接中,只有一個表可以被用作另一個表和第三個表的橋樑。
- 交叉聯結(cross join)結果顯示兩個表所有可能的組合。
- USING可以替代ON,比如:select * from A inner join B on a.id = b.id可以改寫成select * from A inner join B using(id);
- 默認情況下,join等價於inner join。
- 內聯結其實就相當於把多個表根據條件聯結起來,條件越多,結果的行數越少。所以內聯結一直在做減的操作。但是外聯結至少返回其中一個表的所有行。
- 總而言之,左外聯結引用左表檢驗所有的行,右外聯結引用右表檢驗所有的行,全外聯結檢索兩個表的所有行。在所有的這些情況中,沒有匹配的行用空值填充。
- 外連接:left outer join、right outer join和full outer join主要是用來聯結幾張表查看這幾張表中所有行的數據。
- 自聯結:就是自己與自己聯結,雖然是兩張表,但是都是同一張表。用途:在同一張表裏面查找與一條數據相關的信息。比如在信息表裏面查找與張三在一個城市的人,這樣的查詢就是自連接。