什么是扎实的基本功?MySQL 基础知识看看你了解多少

2024-06-23 11:20

本文主要是介绍什么是扎实的基本功?MySQL 基础知识看看你了解多少,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文首发于公众平台:腐烂的橘子

当前很多同学沉迷于“碎片化学习”,问题在于获取到的都是零碎的知识,没有体系化的知识框架,这对于练就扎实的基本功是极其不利的。

怎么办?这时要懂得中庸之道“慢即是快”的道理,系统学一遍,查漏补缺,不要觉得有些你知道就学不下去了,要耐得住性子,系统学习。

下面就来检验下这些知识点你是否都掌握了。

关于 join 的那些事

Inner join

冷知识:join = inner join

select order_id, orders.customer_id
from order 
join customers
on orders.customer_id = customers.customer_id

多库连接

可以通过 join 关联其他库表,这是基本用法。

use sql_inventory;select *
from sql_store.order_items oi
join sql_inventory.products p
on oi.product_id = p.product_id

自连接

join 除了可以关联其他表,也可以关联自己。

use sql_hr;select a.account_id, a.account_name,b.account_id, b.account_name
from t_account_object a
join t_account_object bon a.parent_parent_id = b.account_id

连接超过两张表

不多解释,不断使用 join 就可以了。

use sql_invoicing;select *
from payments p
join clients c
on p.client_id = c.client_id
join payment_methods pm
on p.payment_ 

outer join

这几个等价的关系你了解吗?

  • inner join 也可写作 join
  • left outer join 也可写作 left join
  • right outer join 也可写作 right outer join

using 怎么用

如果关联的字段名相同,using 可以代替 on。

selecto.order_id,c.first_name
from orders o 
join customers cusing (customer_id)
join shippers shusing (shipper_id)

等价于:

selecto.order_id,c.first_name
from orders o 
join customers con c.customer_id = o.customer_id
join shippers shon sh.shipper_id = o.shipper_id 

如果需要多个字段,用逗号分隔:

select *
from order_items oi
join order_item_notes oinusing (order_id, product_id)

自然连接

引擎自己选择连接的列,不推荐使用,因为没有显示指明是怎么关联的。

select *
from order o
natual join customers c

交叉连接

返回两张表所有数据行的笛卡尔积,这个一般也不推荐,因为笛卡尔积是指数级别的。

select *
from customers c
cross join products p
order by c.first_name

等价于

select *
from customers c, orders o
order by c.first_name

union

合并两段查询结果。注意两段的列数要相同,下面写法会报错:

select first_name, last_name
from customers
union
select name
from shippers

因为第一段返回一列,第二段返回两列,以下是正确的:

select first_name
from customers
union
select name
from shippers

这里的列名是 first_name,不是 name,以第一段查询的列名为准

varchar 和 char 的区别

  • varchar(50),保存 5 个字符,则没有其余空间
  • char(50),保存 5 个字符,还有 45 个字符空闲

表的创建、更新、删除、查询

insert 一张表

如果插入其中几个字段,需要写字段,否则可以不写:

insert into orders(customer_id, order_date, status) 
values (1, '2019-01-02', 1);
insert into order_items
values(LAST_INSERT_ID(), 1, 1, 2.95),(LAST_INSERT_ID(), 1, 2, 3.95)

第一个 SQL 加了字段名,第二个没有。

创建表复制

复制整张表:

create table orders_archived as
select * from orders

其中 select * from orders 称为子查询,可以替换成其他复杂的查询语句。

复制其中某几行,还是用 insert into

insert into orders_archived
select *
from orders
where order_date < '2024-01-01'

更新单行

可以设置单行为 null

update invoices
set payment_total = invoice_total * 0.5, payment_date = null
where invoice_id = 1

更新多行

设置 where 选中多行即可。

update 使用子查询

update invoices
set
payment_total = invoice_total * 1.2,
payment_date = due_date
where client_id in (select client_id from clientswhere state in ('CA', 'NY'))

你一定要知道的聚合函数

数值聚合函数

  • MAX():求最大值
  • MIN():求最小值
  • AVG():求平均值
  • SUM():求和
  • COUNT():求数量

having 和 where 区别

  • where 在分组前筛选
  • having 在分组后筛选

with rollup

select state,city,sum(invoice_total) as total_sales
from invoices i
join clients c using (client_id)
group by state, city with rollup

生成总计,不能再用 order by。

ALL 关键字

select *
from invoices
where invoice_total > ALL (select invoice_totalfrom invoiceswhere client_id = 3
)

all 和 max 可以替换,比如可以写成这样:

select *
from invoices
where invoice_total > (select max(invoice_total)from invoiceswhere client_id = 3
)

ANY 关键字

先看一段 SQL:

select * 
from clients
where cliend_id in (select client_idfrom invoicesgroup by client_idhavind count(*) >= 2
)

用 any 可以这样写:

select * 
from clients
where cliend_id = any (select client_idfrom invoicesgroup by client_idhavind count(*) >= 2
)

所以 in 等价于 = any

AVG

select *
from invoices
where invoice_total > (select AVG(invoice_total)from invoiceswhere client_id = i.client_id
)

exists

select *
from clients c
where exists (select client_idfrom invoiceswhere client_id = c.client_id
)

select 子句中的子查询

selectinvoice_id, invoice_total,(select avg(invoice_total)from invoice) as invoice_average,invoice_total - (select invoice_average) as difference
from invoices

数值函数

  • round(5.7345, 2),四舍五入 5.73
  • truncate(5.7345, 2), 截断,5.73
  • ceiling(5.7), 6
  • floor(5.2), 5
  • abs(-5.2), 5.2
  • rand(), 0-1 之间的随机值,如 0.6633075453930605

字符串函数

  • length('sky'),3,字符串长度
  • upper('sky'), SKY
  • lower('SKy'), sky
  • ltrim(' sky '),sky
  • rtrim('sky '), sky
  • trim(' sky '), sky
  • left('Kindergarten', 4), Kind
  • right('Kinderarara', 6), rarara
  • substring('Kindergarten', 3, 5), nderg
  • locate('n', 'Kindergarten'), 3
  • locate('garten', 'Kindergarten'), 7
  • replace('Kindergarten', 'garten', 'garden'), Kindergarden
  • concat('first', 'last'), firstlast

日期函数

  • now(), 2024-06-23 00:34:04
  • curdate(), 2024-06-23
  • curtime(), 00:34:30
  • year(now()), 2024
  • month(now()), 6
  • day(now()), 23
  • hour(now()), 0
  • minute(now()), 35
  • second(now()), 32
  • dayname(now()), Sunday,字符串格式的星期数
  • monthname(now()), June, 字符串格式的月份
  • extract(year from now()), 2024,标准SQL,推荐使用
  • date_format(now(), ‘%y’), 24,两位数年份
  • date_format(now(), ‘%Y’), 2024,四位数年份
  • date_format(now(), ‘%m’), 06,两位数月份
  • date_format(now(), ‘%M’), June,月份名称
  • time_format(now(), ‘%H:%i %p’), 00:36 AM

计算日期和时间

  • date_add(now(), interval 1 day),返回明天的同一时间
  • date_add(now(), interval 1 year),返回明年的同一时间
  • date_sub(now(), interval -1 year),返回明年的同一时间
  • datediff(‘2024-06-02 09:00’, ‘2024-06-07 17:00’), 5
  • datediff(‘2024-06-07 17:00’, ‘2024-06-02 09:00’), -5
  • time_to_sec(‘09:00’), 32400, 表示从零点流逝的秒数
  • time_to_sec(‘09:00’) - time_to_sec(‘09:02’), -120

ifnull 和 coalesce

  • ifnull(shipper_id, 'Not assigned'):如果 shipper_id 为空,返回 Not assigned。即返回非空值
  • coalesce(shipper_id, comments, 'Not assigned'):如果 shipper_id 为空,返回 comments,如果 comments,如果 为空,返回 Not assigned。即返回第一个非空值

if

语法:if(expression, first, second)

select 
product_id, name, 
count(*) as orders,
if (count(*) > 1, 'Many times', 'Once')
from products
join order_items using (product_id)

case

select 
order_id,
casewhen year(order_date) = year(now()) then 'Active' when year(order_date) = year(now()) - 1 then 'Last Year' when year(order_date) = year(now()) - 1 then 'Archived' 
else 'Future'
end as category

MySQL 视图

创建视图

假设我们要多次使用一个查询结果:

selectc.client_id, c.name, sum(invoice_total) as total_sales
from clients c
join invoices i using (client_id)
group by client_id, name

可以创建一个视图:

create view sales_by_client as 
selectc.client_id, c.name, sum(invoice_total) as total_sales
from clients c
join invoices i using (client_id)
group by client_id, name

更改或删除视图

如果想修改视图,有两种办法:

  • 先删除视图,再创建视图
  • 更改视图(更方便)

先删除视图:

drop view sales_by_client

再创建视图:

create view sales_by_client as 
selectc.client_id, c.name, sum(invoice_total) as total_sales
from clients c
join invoices i using (client_id)
group by client_id, name

或直接使用创建或替换视图,更推荐:

create or replace view sales_by_client as
selectc.client_id, c.name, sum(invoice_total) as total_sales
from clients c
join invoices i using (client_id)
group by client_id, name

可以把这段sql保存在.sql文件中,这样可以随时创建视图了。

with option check 子句

如果你先创建了视图,但你可能会使用 update 更新视图里的数据,但是视图展示的还是老数据,会造成数据不一致。为了解决这个问题,你可以在视图里添加 with option check 子句,当 update 会更新掉视图的数据时报错,从而解决数据不一致的问题。

create or replace view sales_by_client as
selectc.client_id, c.name, sum(invoice_total) as total_sales
from clients c
join invoices i using (client_id)
group by client_id, name
with check option

视图的优点是提供了一种抽象,减少了表结构变化带来的影响。

这篇关于什么是扎实的基本功?MySQL 基础知识看看你了解多少的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1087017

相关文章

MySQL MCP 服务器安装配置最佳实践

《MySQLMCP服务器安装配置最佳实践》本文介绍MySQLMCP服务器的安装配置方法,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下... 目录mysql MCP 服务器安装配置指南简介功能特点安装方法数据库配置使用MCP Inspector进行调试开发指

mysql中insert into的基本用法和一些示例

《mysql中insertinto的基本用法和一些示例》INSERTINTO用于向MySQL表插入新行,支持单行/多行及部分列插入,下面给大家介绍mysql中insertinto的基本用法和一些示例... 目录基本语法插入单行数据插入多行数据插入部分列的数据插入默认值注意事项在mysql中,INSERT I

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

MySQL 衍生表(Derived Tables)的使用

《MySQL衍生表(DerivedTables)的使用》本文主要介绍了MySQL衍生表(DerivedTables)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学... 目录一、衍生表简介1.1 衍生表基本用法1.2 自定义列名1.3 衍生表的局限在SQL的查询语句select

MySQL 横向衍生表(Lateral Derived Tables)的实现

《MySQL横向衍生表(LateralDerivedTables)的实现》横向衍生表适用于在需要通过子查询获取中间结果集的场景,相对于普通衍生表,横向衍生表可以引用在其之前出现过的表名,本文就来... 目录一、横向衍生表用法示例1.1 用法示例1.2 使用建议前面我们介绍过mysql中的衍生表(From子句