以下內容節錄PostgreSQL使用手冊
中文參考
原文參考
Chapter 7. Queries
最簡單的形式:
SELECT * FROM table1;
SELECT a, b + c FROM table1;
如果要當calculator可省略table,如下:
SELECT 3 * 4;
Table expression 包含 FROM 也可以包含WHERE, GROUP BY, HAVING.
如果多張Table在FROM裡面,the tables are cross-joined.
Joined Tables
T1 join_type T2 [ join_condition ]
T1 CROSS JOIN T2
T1 INNER JOIN T2
T1 LEFT OUTER OIN T2
T1 RIGHT OUTER JOIN T2
T1 FULL OUTER JOIN T2 /*有的都抓,有缺當缺值*/
ON 後通常接condition
USING (a, b) 簡化the join condition ON T1.a = T2.a AND T1.b =T2.b
SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;
SELECT * FROM t1 INNER JOIN t2 USING (num);
差別在第一種列出兩者的num,後者只列出一次num
SELECT * FROM t1 NATURAL INNER JOIN t2;
NATURAL JOIN 跟 INNER JOIN 差別在 NATURAL JOIN 有一樣欄位名稱才能用
例如:
A Table 有 i ii iii 三個欄位
B Table 有 iii iv v 三個欄位
SELECT A.ii, B.iv
FROM A
NATURAL JOIN B
會出現兩者iii重疊到的ii及iv
結果等同於
SELECT A.ii, B.iv
FROM A
INNER JOIN B
ON A.iii=B.iii;
順便查LEFT JOIN跟LEFT OUTER JOIN有沒有差?
LEFT JOIN 是 LEFT OUTER JOIN 的簡寫
SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;
SELECT * FROM t1 LEFT JOIN t2 USING (num);
一樣只差在第一行的指令結果會多一欄
WHERE 就不贅述了
但下方的三個範例或的的結果是相同的可參考:
FROM a, b WHERE a.id = b.id AND b.val > 5
FROM a INNER JOIN b ON (a.id = b.id) WHERE b.val > 5
FROM a NATURAL JOIN b WHERE b.val > 5
附上一種用法:
SELECT ... FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100
另外是關於GROUP BY & HAVING的用法,下方範例應該是淺顯易懂,不同於WHERE,HAVING使用在GROUP BY的時候:
=> SELECT x, sum(y) FROM test1 GROUP BY x;
x | sum
---+-----
a | 4
b | 5
c | 2
(3 rows)
x | sum
---+-----
a | 4
b | 5
c | 2
(3 rows)
=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;
x | sum
---+-----
a | 4
b | 5
(2 rows)
=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';
x | sum
---+-----
a | 4
b | 5
(2 rows)
x | sum
---+-----
a | 4
b | 5
(2 rows)
=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';
x | sum
---+-----
a | 4
b | 5
(2 rows)
關於SET的使用可參考:
=> SELECT * FROM items_sold;
brand | size | sales
-------+------+-------
Foo | L | 10
Foo | M | 20
Bar | M | 15
Bar | L | 5
(4 rows)
=> SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ());
brand | size | sum
-------+------+-----
Foo | | 30
Bar | | 20
| L | 15
| M | 35
| | 50
brand | size | sales
-------+------+-------
Foo | L | 10
Foo | M | 20
Bar | M | 15
Bar | L | 5
(4 rows)
=> SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ());
brand | size | sum
-------+------+-----
Foo | | 30
Bar | | 20
| L | 15
| M | 35
| | 50
另一個CUBE的用法可參考等同於GROUPING SETS的結果,如下:
CUBE ( a, b, c )
等於
GROUPING SETS (
( a, b, c ),
( a, b ),
( a, c ),
( a ),
( b, c ),
( b ),
( c ),
( )
)
( a, b, c ),
( a, b ),
( a, c ),
( a ),
( b, c ),
( b ),
( c ),
( )
)
或者
CUBE ( (a, b), (c, d) )
等同於
GROUPING SETS (
( a, b, c, d ),
( a, b ),
( c, d ),
( )
)
( a, b, c, d ),
( a, b ),
( c, d ),
( )
)
ROLLUP的使用則如下:
ROLLUP ( a, (b, c), d )
等同於
GROUPING SETS (
( a, b, c, d ),
( a, b, c ),
( a ),
( )
)
( a, b, c, d ),
( a, b, c ),
( a ),
( )
)
Multiple Grouping items
GROUP BY a, CUBE (b, c), GROUPING SETS ((d), (e))
等同於
GROUP BY GROUPING SETS (
(a, b, c, d), (a, b, c, e),
(a, b, d), (a, b, e),
(a, c, d), (a, c, e),
(a, d), (a, e)
)
(a, b, c, d), (a, b, c, e),
(a, b, d), (a, b, e),
(a, c, d), (a, c, e),
(a, d), (a, e)
)
Alias
以a代替my_table這張表,b代替your_table這張表,用法與SAS中PROC SQL以t1,t2表示的方式相同
SELECT a.* FROM my_table AS a JOIN your_table AS b ON ...
SELECT LIST ITEMS
SELECT a "value", b + c AS sum FROM …
等同於
SELECT a AS “value”, b + c AS sum FROM …
如果新命的名稱是關鍵字,需用雙引號表示,避免日後新增關鍵字,因此建議AS後或欄位名稱都用雙引號標示
Combining Query
query1 UNION [ALL] query2
聯集,不加ALL會DISTINCT
query1 INTERSECT [ALL] query2
交集,不加ALL會DISTINCT
query1 EXCEPT [ALL]query2
回傳query1的結果中不包含在query2的,不加ALL會DISTINCT
Order By
可以是輸出的欄位或編號
SELECT a + b AS sum, c FROM table1 ORDER BY sum;
SELECT a, max(b) FROM table1 GROUP BY a ORDER BY 1;
LIMIT & OFFSET
限制回傳行數
SELECT select_list
FROM table_expression
[ ORDER BY ... ]
[ LIMIT { number | ALL } ] [ OFFSET number]
LIMIT在number行前,LIMIT ALL等同於沒寫LIMIT
OFFSET表示跳過number行,OFFSET等同於沒寫OFFSET
VALUE的使用.一個括號內表示一個資料列,所以下方範例有三列資料列:
=> SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);
num | letter
-----+--------
1 | one
2 | two
3 | three
(3 rows)
VALUES (1, 'one'), (2, 'two'), (3, 'three');
等同於
SELECT 1 AS column1, 'one' AS column2
UNION ALL
SELECT 2, 'two'
UNION ALL
SELECT 3, 'three';
留言
張貼留言