case ... when
case ... when有点类似于golang里面的switch
语法:
select
case 字段
when 值1 then 替换值1 -- 如果字段为"值1",那么使用"替换值1"替代
when 值2 then 替换值2 -- 同理
when ... then ... -- when then 条件可以写多个
when ... then ...
else '默认替换值' -- 默认值,可以不写,如果不写,那么就是NULL
end -- 标记一个case when语句的结束
from t
select age from t limit 5;
/*
44
54
45
39
46
*/
-- 使用case when
select
case age
when 44 then '四十四'
when 54 then '五十四'
else '不是四十四,也不是五十四'
end
from t limit 5;
/*
四十四
五十四
不是四十四,也不是五十四
不是四十四,也不是五十四
不是四十四,也不是五十四
*/
-- 如果没有else
select
case age
when 44 then '四十四'
when 54 then '五十四'
end
from t limit 5;
/*
四十四
五十四
null
null
null
*/
-- 不再when then里面的值会走else,但是没有else,那么会是null
语法:
-- 另一种方式是,case 后面不跟字段,如果跟字段的话那么when后面必须是一个具体的值
-- 可以把字段写在when里面,这样就可以带条件了
select
case
when 条件1 then 替换值1 -- 如果满足'条件1',那么使用"替换值1"替代
when 条件2 then 替换值2 -- 同理
when ... then ... -- when then 条件可以写多个
when ... then ...
else '默认替换值' -- 默认值,可以不写,如果不写,那么就是NULL
end -- 标记一个case when语句的结束
from t
select
case
when age > 30 and age < 40 then '30~40'
when age > 40 and age < 50 then '40~50'
else '50~'
end
from t limit 5;
/*
40~50
50~
40~50
30~40
40~50
*/
with ... as语句
pgsql的with语句主要用于包含复杂查询的sql语句中,因为它可以将一个查询变成一张临时表
-- 此时tmp1就是一张临时表
-- 内部就是里面筛选条件得到的结果,另外这里面是可以写复杂的逻辑的
with tmp1 as (
select max(age) as age
from t
)
select * from t where age = (select * from tmp1);
/*
2 01010004165 54 26.8 大学本科毕业 工程师 管理人员 1992-09-05
*/
-- with as里面是可以创建多个临时表的,记得使用逗号隔开
/*
with tmp1 as (
...
), tmp2 as (
...
), tmp3 as (
...
)
select ... from ...
*/
自定义函数
-- pgsql如何自定义函数
create function 函数名
returns 类型
as
$$
begin
...
...
...
end;
$$ language plpgsql;
-- 定义一个函数,接收两个字符串,功能是先把它们都变成大写,然后再使用空格拼接起来
create function upper_concat(a text, b text)
-- 接收两个参数a和b,都是text类型
-- 表示返回一个text类型的数据
returns text
as -- 固定写法
$$ -- 固定写法
begin
a = upper(a); -- 转成大写
b = upper(b);
return a || ' ' || b;
end;
$$ language plpgsql;
select upper_concat('name', 'satori');
/*
NAME SATORI
*/
一旦当我们定义了之后,pgsql数据库中就已经存在这个函数了,那么就不能再次定义这个函数了,当然pgsql是支持函数重载的,如果参数不同的话,还是可以定义的。
-- 但是一般我们不这么定义
-- 而是会多加上一个or replace,这样如果重名且参数一样的话,会进行覆盖
create or replace function
-- 但是这样无法保证,是否别人碰巧定义了一个跟你一样、而且参数个数类型都一样的参数
-- 这种概率是有的,因此最保险的办法是我们定义一个函数,使用完之后要删掉
drop function function_name(params type)
-- 删除函数,不能只写函数名,参数的类型都要按照顺序写清楚
-- 原因刚才说过了,pgsql是支持函数重载的,如果函数参数和类型不一样,那么即使函数名一样
-- 也被视为不同的函数,如果只指定函数名,那么pgsql不知道要删除哪一个,所以必须也要按顺序指定类型
此外,如果我们需要创建新的变量呢?
create or replace function upper_concat(a text, b text)
returns text
as
$$
DECLARE
-- begin end是我们要写的语句块
-- 但是里面用到了新的变量c,因此需要在declare语句中声明
c text ;
begin
a = upper(a); -- 转成大写
b = upper(b);
-- 如果这里不给c赋值,c这个变量也是存在的,因为声明了,但是值为NULL
c = '哈哈哈';
return a || ' ' || b || c;
end;
$$ language plpgsql;
select upper_concat('name', 'satori');
/*
NAME SATORI哈哈哈
*/
drop function upper_concat(text, text)
另外函数里面是支持默认参数的
create or replace function upper_concat(a text default 'you', b text default '666')
returns text
as
$$
DECLARE
c text ;
begin
a = upper(a); -- 转成大写
b = upper(b);
c = '哈哈哈';
return a || ' ' || b || c;
end;
$$ language plpgsql;
select upper_concat();
/*
YOU 666哈哈哈
*/
-- 也可以给指定的参数赋值,但是注意不要同一个参数重复赋值
-- 类似于python,关键字参数一定要在位置参数的后面
select upper_concat(b => '777');
/*
YOU 777哈哈哈
*/
drop function upper_concat(text, text)
for循环与if语句
求fibnacci数列
create or replace function fibnacci(n int)
returns int
as
$$
declare
tmp int;
a int = 1;
b int = 1;
begin
-- pgsql的for循环是包含n的
for num in 1 .. n loop
tmp = a;
a = a + b;
b = tmp;
end loop;
return a;
end;
$$ language plpgsql;
select fibnacci(12);
/*
377
*/
create or replace function fibnacci(n int)
returns int
as
$$
declare
-- 空的也是可以的
begin
if n < 1 then
return 1;
end if;
return fibnacci(n - 1) + fibnacci(n - 2);
end;
$$ language plpgsql;
select fibnacci(12);
/*
377
*/
/*
if condition then
...
else if condition then
...
else if condition then
...
else
...
end if;
for var in 1 .. 10 loop
...
end loop;
*/
alter语句
增加一列
alter table <表名> add column <列名> <类型>
--比如
alter table t1 add column new_col varchar(255)
删除一列
alter table <表名> drop column <列名>
-- 比如
alter table t1 drop column new_col
重命名列
alter table <表名> rename column <原列名> to <新列名>
-- 比如
alter table t1 rename column age to new_age
-- 如果是表的重命名的话
alter table <表名> rename to <新表名>
修改字段类型
alter table <表名> alter column <列名> type <类型>
-- 比如
alter table t1 column age type bigint