sql 函数/条件语句/视图

第七章:常用函数、条件语句

7.1 数值函数 numeric functions

select round(3.14159, 2),  # 3.14
	ceiling(4.4),  # 5
	floor(4.4),    # 4
	abs(-2),        # 2
	rand();        # 生成0-1随机数

7.2 字符串函数 string functions

select length('ysy'),
	upper('ysy'),
    lower('YSy'),
    
    # 去空格
    ltrim('    y  sy  '),   # 去掉字符前面的空格
    rtrim('    y  sy  '),   # 去掉字符后面的空格
    trim('    y  sy  '),    # 去掉前+后空格(中间的还在)
    
    # 截取 切片(py) / substr(r)
    left('Kindergarten', 4),   # 前4个
    right('Kindergarten', 6),  # 后6个
    substring('Kindergarten', 3, 2),   # 从第3个(起始位置)往后的2个字母
    
    # 寻找 in(py) / grep (r) 
    locate('瓜','想吃瓜的杨杨吃不到瓜'), # 返回“瓜”第一次出现的位置3
    locate('寡','想吃瓜的杨杨吃不到瓜'), # 找不到的话返回 0
    locate('吃瓜','想吃瓜的杨杨吃不到瓜'), 
    
    # 替换 replace(py) / gsub(r)
    replace('Kindergarten', 'garten','garden'),
    
    # 连接 +(py) / paste (r)
    concat('aa','+','bb')   # 输出aa+bb
;

use sql_store;
select concat(first_name, ' ', last_name) as full_name,
	length(first_name) + length(last_name) as length_of_name,
    concat('customer','_',left(last_name,1))
from customers;

7.3 日期函数

select 
	# 获取当前时间
	now(),       # 获取当前time
	curdate(),   # 获取当前日期
    curtime(),   # 获取当前时刻
    
    # 提取时间的年月日
    year(now()),     # 同理还有 month day second
    dayname(now()),  # 获取星期几
    monthname(now()), # 获取月份名称
    
    # extract提取
    extract(year from now())-1;  

select year(order_date),
	monthname(order_date),
    day(order_date),
    dayname(order_date)
from orders;

select * 
from orders
where year(order_date) = year(now())-1;

7.4 格式化日期和时间 类似格式化输出这样

select date_format(now(),'%d-%m-%y'),
	date_format(now(),'%y年%m月%d日%p');

7.5 计算日期和时间间隔

select now(),
	# 前后几天/月/日
	date_add(now(), interval - 4 day),
    date_add(now(), interval 3 month),
    datediff('2020-12-12',now()),  # 还有38天过生日嘿嘿
    datediff('2020-12-12','1997-12-12');   # 已经活了8401天

7.6 if null & coalesec

use sql_store;
select 
	order_id,
    # ifnull 其实就是 if x=null:then a; else:x
    ifnull(shipper_id, comments) as shipper_id_1,
    # coalesce(a,b,c)如果a列是空就用b列内容,如果ab都空就填c
    coalesce(shipper_id, comments, 'not assigned') as shipper_id_2
from orders;

select concat(first_name, ' ', last_name) as customer,
	coalesce(phone,'unknown')as phone
from customers;

7.7 if

select 
	order_id,
    order_date,
	# if(expression, true, false)
	if(year(order_date) < 2019 ,'archievd','active') as order_status
from orders;


select 
	p1.product_id,
	name,
    (select count(product_id) 
		from order_items 
        where product_id = p1.product_id) as order_num,
	if((select order_num) = 0, 'never', 'at least once') as freq
from products p1
order by order_num desc;

7.8 case 运算符

select 
	order_id,
    order_date,
    case
		when year(order_date) = year(now()) - 1 then '去年'
        when year(order_date) = year(now()) - 2 then '前年'
        when year(order_date) <= year(now()) - 3 then '老早之前'
        else '将来'
	end as category
from orders;

select
	customer_id,
    concat(first_name, ' ', last_name) as customer_name,
    case 
		when points >= 3000 then 'gold'
        when points >= 2000 then 'silver'
        else 'bronze'
	end as category
from customers
order by points desc;

第八章:视图

/*
创建视图,很像数据透视表 ~ 注意视图不存储数据~
更改或者删除视图
可更新视图
with option check

视图的优点:
方便简洁、减少改动带来的影响
*/

8.1 创建视图

use sql_invoicing;
## 1.create
create view sales_by_client as
select 
	c.client_id,
    c.name,
    sum(invoice_total) as total_sales
from clients c
join invoices i using(client_id)
group by client_id;
## 2.使用
select * 
from sales_by_client
join clients using(client_id);

create view balance_client as
select
	client_id,
    name,
    sum(invoice_total - payment_total) as balance_total
from clients c
join invoices i using(client_id)
group by client_id;
select * from balance_client;


## 8.2 更改或删除视图
```{sql}
drop view balance_client;
create or replace view balance_client as
select
	client_id,
    name,
    sum(invoice_total - payment_total) as balance_total
from clients c
join invoices i using(client_id)
group by client_id;
### 保存方法——单独一个sql文件,文件名和视图名一样

8.3 可更新视图

/*
如果视图中没有:

  • distinct / 聚合函数 / group by / having / union
    那么叫做可更新视图(可以在insert update delete语句中使用)
    */
create or replace view invoices_with_balance as
select
	invoice_id,
    number as phone_number,
    client_id,
    invoice_total,
    payment_total,
    invoice_total - payment_total as balance_total,
    invoice_date,
    due_date,
    payment_date
from invoices
where invoice_total > payment_total;
    
# 更新视图1
delete from invoices_with_balance
where invoice_id = 1;
# 更新视图2
update invoices_with_balance
set due_date = date_add(due_date, interval 2 day)
where invoice_id = 2;

8.4 with option check

update invoices_with_balance
set payment_total = invoice_total
where invoice_id = 3;     # 会发现因为balance=0,直接drop掉了

create or replace view invoices_with_balance as
select
	invoice_id,
    number as phone_number,
    client_id,
    invoice_total,
    payment_total,
    invoice_total - payment_total as balance_total,
    invoice_date,
    due_date,
    payment_date
from invoices
where invoice_total > payment_total
with check option;  # 加上这一行之后,防止行被删除