什么是扎实的基本功?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索引四(组合索引)

单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引;组合索引,即一个索引包含多个列。 因为有事,下面内容全部转自:https://www.cnblogs.com/farmer-cabbage/p/5793589.html 为了形象地对比单列索引和组合索引,为表添加多个字段:    CREATE TABLE mytable( ID INT NOT NULL, use

mysql索引三(全文索引)

前面分别介绍了mysql索引一(普通索引)、mysql索引二(唯一索引)。 本文学习mysql全文索引。 全文索引(也称全文检索)是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。 在MySql中,创建全文索引相对比较简单。例如:我们有一个文章表(article),其中有主键ID(

mysql索引二(唯一索引)

前文中介绍了MySQL中普通索引用法,和没有索引的区别。mysql索引一(普通索引) 下面学习一下唯一索引。 创建唯一索引的目的不是为了提高访问速度,而只是为了避免数据出现重复。唯一索引可以有多个但索引列的值必须唯一,索引列的值允许有空值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该使用关键字UNIQUE,把它定义为一个唯一索引。 添加数据库唯一索引的几种

mysql索引一(普通索引)

mysql的索引分为两大类,聚簇索引、非聚簇索引。聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引则不同。聚簇索引能够提高多行检索的速度、非聚簇索引则对单行检索的速度很快。         在这两大类的索引类型下,还可以降索引分为4个小类型:         1,普通索引:最基本的索引,没有任何限制,是我们经常使用到的索引。         2,唯一索引:与普通索引

【服务器运维】MySQL数据存储至数据盘

查看磁盘及分区 [root@MySQL tmp]# fdisk -lDisk /dev/sda: 21.5 GB, 21474836480 bytes255 heads, 63 sectors/track, 2610 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical)

硬件基础知识——自学习梳理

计算机存储分为闪存和永久性存储。 硬盘(永久存储)主要分为机械磁盘和固态硬盘。 机械磁盘主要靠磁颗粒的正负极方向来存储0或1,且机械磁盘没有使用寿命。 固态硬盘就有使用寿命了,大概支持30w次的读写操作。 闪存使用的是电容进行存储,断电数据就没了。 器件之间传输bit数据在总线上是一个一个传输的,因为通过电压传输(电流不稳定),但是电压属于电势能,所以可以叠加互相干扰,这也就是硬盘,U盘

SQL Server中,查询数据库中有多少个表,以及数据库其余类型数据统计查询

sqlserver查询数据库中有多少个表 sql server 数表:select count(1) from sysobjects where xtype='U'数视图:select count(1) from sysobjects where xtype='V'数存储过程select count(1) from sysobjects where xtype='P' SE

SQL Server中,always on服务器的相关操作

在SQL Server中,建立了always on服务,可用于数据库的同步备份,当数据库出现问题后,always on服务会自动切换主从服务器。 例如192.168.1.10为主服务器,12为从服务器,当主服务器出现问题后,always on自动将主服务器切换为12,保证数据库正常访问。 对于always on服务器有如下操作: 1、切换主从服务器:假如需要手动切换主从服务器时(如果两个服务

SQL Server中,isnull()函数以及null的用法

SQL Serve中的isnull()函数:          isnull(value1,value2)         1、value1与value2的数据类型必须一致。         2、如果value1的值不为null,结果返回value1。         3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。        如

SQL Server中,添加数据库到AlwaysOn高可用性组条件

1、将数据添加到AlwaysOn高可用性组,需要满足以下条件: 2、更多具体AlwaysOn设置,参考:https://msdn.microsoft.com/zh-cn/library/windows/apps/ff878487(v=sql.120).aspx 注:上述资源来自MSDN。