pg手册小结
Where
不等运算符 (<>
)运算符,等同于!=
。 如果数据库字段不为空,也不能查询到。数据库字段非空很有必要。
sql
-- 不会查询到name为空的数据
select * from document_directories where name <> '中国';
-- 如果字段不是非空的,需要额外考虑到
select * from document_directories where name <> '中国' or name is null;
-- 不会查询到name为空的数据
select * from document_directories where name <> '中国';
-- 如果字段不是非空的,需要额外考虑到
select * from document_directories where name <> '中国' or name is null;
BETWEEN
运算符用于检查一个值是否位于一个值区间之内(包含边界),如果这个值介于指定的区间,BETWEEN
运算符返回真,否则返回假。
sql
select *
from document_directories
where length(name) between 3 and 4
select *
from document_directories
where length(name) between 3 and 4
Order By
- 可使用
NULLS FIRST
或者NULLS LAST
改变对NULL
值的处理规则。- NULLS FIRST: null 值在非 null 值之前。
- NULLS LAST: null值在非null值之后。
- 默认情况下,PostgreSQL 采用升序排序时采用
NULLS LAST
,降序排序时采用NULLS FIRST
也就是说, PostgreSQL 默认 null 值比非 null 值大。
Order By
自定义排序:
sql
select *
from document_directories
ORDER BY CASE name
WHEN '中国' THEN 1
WHEN '北京' THEN 2
WHEN '南京' THEN 3
END;
select *
from document_directories
ORDER BY CASE name
WHEN '中国' THEN 1
WHEN '北京' THEN 2
WHEN '南京' THEN 3
END;
fetch和limit的区别
OFFSET子句必须在FETCH子句之前。但是,在PostgreSQL中,OFFSET和FETCH子句可以以任何顺序出现。
FETCH子句在功能上等同于LIMIT子句。如果您计划使您的应用程序与其他数据库系统兼容,您应该使用FETCH子句,因为它遵循标准SQL。
sql
select * from document_directories FETCH FIRST 5
ROWS ONLY;
select * from document_directories FETCH FIRST 5
ROWS ONLY;
DISTINCT
SELECT DISTINCT
返回一个没有重复行的结果集。DISTINCT
后面可以指定一个列或者多个列,也可以用*
。DISTINCT
将所有的NULL
视为相等的,并只保留一个。DISTINCT ON
子句用来返回每组重复值的第一个行。- 可以一同使用 DISTINCT 和 COUNT 关键词,来计算非重复结果的数目。
select count(distinct name) from document_directories
IN
带有子查询的 PostgreSQL IN
的表达式都可以使用 EXISTS
运算符 改写,并且 EXISTS
表达式具有更好的效率。上面的语句等同于以下使用 EXISTS
的语句:
sql
SELECT COUNT(*)
FROM film
WHERE film_id IN ( SELECT film_id FROM inventory );
SELECT COUNT(*)
FROM film f
WHERE EXISTS (
SELECT 1
FROM inventory i
WHERE i.film_id = f.film_id
);
SELECT COUNT(*)
FROM film
WHERE film_id IN ( SELECT film_id FROM inventory );
SELECT COUNT(*)
FROM film f
WHERE EXISTS (
SELECT 1
FROM inventory i
WHERE i.film_id = f.film_id
);
LIKE
ilike
忽略大小写
sql
select * from document_directories where pinyin ilike 'eee'
select * from document_directories where pinyin ilike 'eee'
%
匹配零或多个任意字符。_
匹配单个任意字符。- 举例
a_
匹配以字符a
开头长度为 2 字符串 - 举例
_a
匹配以字符a
结尾长度为 2 字符串。
- 举例
- 如果需要匹配通配符,则需要使用
\
转义字符,如\%
和\_
。
EXISTS
EXISTS
一般用在WHERE
子句中。EXISTS
是一个单目操作符,它需要一个子查询subquery
作为参数。- 如果子查询
subquery
返回了至少一行(不论行中的值是否为NULL
),则EXISTS
的计算结果为TRUE
,否则计算结果为FALSE
。 EXISTS
运算时,一旦子查询找到一个匹配的行,EXISTS
运算就会返回。这对提高查询新能很有帮助。EXISTS
不关心子查询中的列的数量或者名称,它只在乎子查询是否返回行。所以在EXISTS
的子查询中,无论你是使用SELECT 1
还是SELECT *
,亦或是SELECT column_list
,都不影响EXISTS
运算的结果。NOT EXISTS
则是EXISTS
的否定操作。
ALL
判断元素是否都满足,需要根据运算符进行比较。
sql
WHERE expr1 > ALL (subquery)
SELECT 2 = ALL(ARRAY[1, 2, 3]); -- false
SELECT 2 > ALL(ARRAY[1, 2, 3]); -- false
SELECT 0 < ALL(ARRAY[1, 2, 3]); -- true
SELECT 0 <> ALL(ARRAY[1, 2, 3]); -- 判断都不等于
WHERE expr1 > ALL (subquery)
SELECT 2 = ALL(ARRAY[1, 2, 3]); -- false
SELECT 2 > ALL(ARRAY[1, 2, 3]); -- false
SELECT 0 < ALL(ARRAY[1, 2, 3]); -- true
SELECT 0 <> ALL(ARRAY[1, 2, 3]); -- 判断都不等于
如果子查询不返回任何行,则 ALL 运算符的计算结果始终为真。
ANY
要检查一个数组中是否至少存在一个满足条件的值
HAVING
- group by 之后,不能用where过滤列,因此有了having
HAVING
子句用于为带有 GROUP BY
子句的分组查询指定过滤条件。HAVING
看起来与 WHERE
相似,虽然他们都是指定过滤条件,但是他们的区别是: WHERE
子句指定的条件用于过滤表中的行,而 HAVING
子句指定的条件用于过滤分组。
sql
SELECT name, count(*) t
FROM document_directories
GROUP BY name
HAVING count(*) > 1
SELECT name, count(*) t
FROM document_directories
GROUP BY name
HAVING count(*) > 1
GROUPING SETS/ ROLLUP
可以看做对多个group by进行了union all的操作。
sql
SELECT rating, rental_rate, count(*) FROM film
GROUP BY GROUPING SETS ((rating), (rental_rate), ())
ORDER BY rating, rental_rate;
SELECT rating, rental_rate, count(*) FROM film
GROUP BY GROUPING SETS ((rating), (rental_rate), ())
ORDER BY rating, rental_rate;
ROLLUP
子句都可以使用 GROUPING SETS
子句实现,比如:
ROLLUP(a, b)
等效于GROUPING SETS((a,b), (a), ())
。ROLLUP(a, b, c)
等效于GROUPING SETS((a,b,c), (a,b), (a), ())
。