sql(基于mysql)速记一

一.概述

首先这是之前一版极其琐碎的blog的链接.然后这篇博客不会涉及存储过程触发器等内容(后续会补充),仅仅按照增删改查这四个点来做基本的介绍以及记录,毕竟工作中很大一部分需要的也是这些内容~

二.素材准备

为这次的记录建好database以及user.(表结构素材来自mysql必知必会)

create database notereview;

create user review@localhost identified by 'xxxxx';

grant all on notereview.* to review@localhost;

flush privileges;

三.查询

基础语句

查询子语句有一个基本的模板:

    FROM xxx WHERE xxx GROUP BY xxx HAVING xxxx ORDER BY xxx LIMIT xxxxx

WHERE和条件连接

这里的WHERE就是查询条件,简单的条件过滤比如 =,<>,!=,<,>,<=,>=,BETWEEN,IN,NOT等.

还有就是对于NULL的检查:IS NULL,IS NOT NULL

上面是使用单条子语句所可能用到的关键词,如果是多条子语句可以通过AND 或者 OR 连接.其中 AND 的优先级是高于 OR的.也就是说:

SELECT a,b,c FROM tableName WHERE conditionA OR conditionB AND conditionC;

相当于是查询同时满足条件B和C,或者满足条件A的数据.举个例子:

create table if not exists products(
    prod_id varcahr(10) not null auto_increment,
    vend_id int not null,
    prod_name varchar(255) not null,
    prod_price decimal(10,2) not null,
    prod_desc text not null,
    primary key(prod_id)
)engine = InnoDb default charset=utf8mb4 comment = '产品表';
SELECT prod_name,vend_id,prod_price FROM products  WHERE vend_id = 1002 OR vend_id = 1003 AND prod_price >= 10;
prod_name vend_id prod_price
Detonator 1003 13.00
Bird seed 1003 10.00
Fuses 1002 3.42
Oil can 1002 8.99
Safe 1003 50.00

其中Fuses的价格为3.42不满足大于等于10的要求但是满足了vend_id为1002的要求.

LIMIT 和 ORDER BY

然后是LIMIT以及ORDER BY,基础模板为:

    xxx ORDER BY xxxx [DESC][,xxxx [desc]] LIMIT index[,offset];

也就是说按照一定规则排序后,从index行开始(包含index),返回最多offset行数据,这里需要注意的是index是从0开始计算的,也就是说LIMIT 1,1其实返回的是第二行.

ORDER BY 默认是升序,如果是DESC则是降序,其中可以按照多个字段排序,实际结果是按照排序字段的出现的优先级来确定的,举个例子:

SELECT prod_name,vend_id,prod_price FROM products where prod_price >10 ORDER BY prod_price DESC,vend_id ASC;
prod_name vend_id prod_price
JetPack 2000 1005 55.00
Safe 1003 35.00
JetPack 1000 1005 35.00
2 ton anvil 1001 14.99
Detonator 1003 13.00

这边的结果可以看出虽然 JetPack 1000 的vend_id 也是1005但是排序的第一条件是按照prod_price 降序,所以他不能处在第一位,又因为第二个条件是按照 vend_id 升序,所以他最终处在第三位.

SELECT prod_name,vend_id,prod_price FROM products where prod_price >10 ORDER BY prod_price DESC,vend_id ASC limit 2,10;
prod_name vend_id prod_price
JetPack 1000 1005 35.00
2 ton anvil 1001 14.99
Detonator 1003 13.00

这里的结果对比上面的可以看出LIMIT 2,10 确实是从第三条开始返回的,如果数据不够则会返回他所能返回的最多的数据.

GROUP BY 和 HAVING

按照上面的顺序,接下来是分组查询GROUP BYHAVING.这两者一般配合使用.HAVING 可以当成是在使用GROUP BY时的WHERE,用来过滤分组后的数据.其中SELECT 后接的表字段(聚合函数除外)必须出现在GROUP BY后.举个例子,查询products表中能够提供多种产品的商户(即产品多余一种),列出商户id以及所能提供的产品数量并按照产品种类数降序排序列出.

SELECT vend_id,count(*) AS prods from products GROUP BY vend_id HAVING prods > 1 ORDER BY prods DESC;

结果如下:

vend_id prods
1003 7
1001 3
1002 2
1005 2

这里列出几个常用的聚合函数:

聚合函数 作用
AVG() 返回某列的平均值
COUNT() 返回某列的行数
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和

like 和正则

这边 like和正则简单提下,因为效率问题推荐放在搜索条件的最后面

WHERE xxxx  like 'xxx'

SELECT  prod_id FROM products WHERE prod_id LIKE 'JP%';
prod_id
JP1000
JP2000

%表示这里可以出现0,1或多个字符.这条语句相当于查询JP开头的数据(注意NULL不会匹配)

同样也可以通过正则来达到一样的效果:

SELECT  prod_id FROM products WHERE prod_id REGEXP 'JP*';

# 这个则不行,因为binary相当于是大小写敏感匹配
SELECT  prod_id FROM products WHERE prod_id REGEXP BINARY 'jp*';

联结查询

等值联结/内部联结

这个其实就是我们常用的 INNER JOIN或者多表条件查询

#等值联结 
SELECT a.x,b.x FROM a,b WHERE a.xxx = b.xxx;
#内联结
SELECT a.x,b.x FROM a INNER JOIN b ON a.xxx = b.xxx;

这里相当于是那表a的每一行和表b的每一行去做匹配并留下符合条件的数据

这里有个特殊的比如自联结:

SELECT p1.prod_id,p1.prod_name FROM products AS p1,products AS p2 WHERE p1.vend_id = p2.vend_id AND p2.prod_id = 'DTNTR';

这里使用了别名是因为是表products和自己联结防止指代不情.这句sql的结果是挑选DTNTR的商户所能生产的所有商品

结果如下:

prod_id prod_name
DTNTR Detonator
FB Bird seed
FC Carrots
SAFE Safe
SLING Sling
TNT1 TNT (1 stick)
TNT2 TNT (5 sticks)

另外的LEFT JOIN,RIGHT JOIN就是所谓的左联结右联结.什么联结就是以那边的数据为准,那边的数据最全,如果右边没有匹配的数据则以NULL的形式展示.

组合查询

UNION:其实是相当于将多条SELECT的结果组合。默认是去除重复行的,UNION ALL 则是不去重哒

# 结果见表1
SELECT vend_id,prod_id,prod_price FROM products WHERE prod_price <= 5;

#结果见表2
SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN(1001,1002);

#结果见表3
SELECT vend_id,prod_id,prod_price FROM products WHERE prod_price <= 5 UNION SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN(1001,1002);

#结果见表4
SELECT vend_id,prod_id,prod_price FROM products WHERE prod_price <= 5 UNION  ALL SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN(1001,1002);

表1:

vend_id prod_id prod_price
1003 FC 2.50
1002 FU1 3.42
1003 SLING 4.49
1003 TNT1 2.50

表2:

vend_id prod_id prod_price
1001 ANV01 5.99
1001 ANV02 9.99
1001 ANV03 14.99
1002 FU1 3.42
1002 OL1 8.99

表3:

vend_id prod_id prod_price
1003 FC 2.50
1002 FU1 3.42
1003 SLING 4.49
1003 TNT1 2.50
1001 ANV01 5.99
1001 ANV02 9.99
1001 ANV03 14.99
1002 OL1 8.99

表4:

vend_id prod_id prod_price
1003 FC 2.50
1002 FU1 3.42
1003 SLING 4.49
1003 TNT1 2.50
1001 ANV01 5.99
1001 ANV02 9.99
1001 ANV03 14.99
1002 FU1 3.42
1002 OL1 8.99

这里因为是将结果合并,所以查询字段必须一致~

四.插入

这个则是insert语句

 INSERT INTO targetName(columnName[,columnName]…) values(columnValue[,columnValue])[,(…)];

这里再提下迁移数据到新表:

INSERT INTO newTable SELECT * FROM oldTable;

#如果结构不一致的话

INSERT INTO 新表(字段1,字段2,.......) SELECT 字段1,字段2,...... FROM 旧表;

五.删除

DELETE FROM tableName WHERE xxx = xxx;

这里记得注意WHERE条件~
然后 TRUNCATE TABLE tableName 不过这个需要注意的是他不会激活触发器,并且不会涉及事务,所以效率很高但是注意备份数据,毕竟不能回滚.

六.更新

UPDATE targetName SET columnName = xxx [,columnName2 = xxxx] WHERE xxx = xxxx;
UPDATE products SET prod_price = 35.00 WHERE prod_id ='SAFE';

同样不要忘记WHERE 条件哈~

七.几个练习(from leetcode-cn)

交换工资(?性别)

给定一个 salary 表,如下所示,有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。

注意,您必只能写一个 Update 语句,请不要编写任何 Select 语句。

id name sex salary
1 A m 2500
2 B f 1500
3 C m 5500
4 D f 500
# 这里使用了 CASE WHEN
UPDATE salary
SET
    sex = CASE sex
        WHEN 'm' THEN 'f'
        ELSE 'm'
    END;


# if的话
UPDATE salary
SET 
 sex = IF(sex='m','f','m');

# 这里就不涉及代码思路解决了比如字符串变换

超过经理收入的员工

Employee 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,此外还有一列对应员工的经理的 Id。

Id Name Salary ManagerId
1 Joe 70000 3
2 Henry 80000 4
3 Sam 60000 NULL
4 Max 90000 NULL
SELECT  a.Name AS Employee   FROM Employee AS a,Employee AS b where a.ManagerId = b.Id AND a.Salary > b.Salary;

不订购任何东西的客户

某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。

Customers 表:

Id Name
1 Joe
2 Henry
3 Sam
4 Max

Orders 表:

Id CustomerId
1 3
2 1
SELECT Name AS Customers from Customers  where Id NOT IN (select CustomerId from Orders);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 这一篇最主要是记录下命令,方便以后查找 使用Mysql 创建数据库 create database mysql_t...
    Treehl阅读 577评论 0 0
  • 表 存储在表中的数据是同一种类型的数据或清单。 数据库中的表有为一个名字来标识自己。 表具有一些特性,这些特性定义...
    蛐蛐囍阅读 1,314评论 0 7
  • 第三课: 排序检索数据 distinct关键字:distinct 列名1,列名2,列名3DISTINCT 关键字会...
    VictorBXv阅读 1,475评论 0 8
  • 先看下运行效果。 主要代码部分。ViewController创建PageViewController 封装SubT...
    我想走走阅读 3,263评论 0 4
  • 时光总是过的很快,不知不觉间,我们已然到了从此记忆里的家乡只有冬夏再无春秋的日子。 我的儿童时光是在一个小城市的...
    小鲜肉都是我家的阅读 188评论 0 0