最近参加了一些公司的实习生招聘的面试,发现很多基本的知识和概念已经很模糊了,很多东西需要重新学习一下,所以准备在学习的过程中,写一些博客,用来整理一下自己的思路。第一篇就从日常积累的SQL开始吧。
SQL注意
- SQL的部分语法不是对所有的DBMS都统一的。许多DBMS厂商对SQL进行了扩展。本文主要是MySql为基础。
- SQL语句不区分大小写。
- SQL语句会忽略所有的空格。
1检索
1.1基本检索
1.1.1检索单个列
select prod_name from products;
Note
查询结果未经过排序
1.1.2检索多个列
select prod_id, prod_name, prod_price
from products;
1.1.3检索所有列
select * from products;
1.1.4检索不同的值
select distinct vend_id from products;
Note
distinct关键字作用于所有的列,不仅仅是跟在其后的那一列。
1.1.5限制结果
select prod_name
from products limit 5 offset 5;
Note
limit 5 offset 5返回从第5行起的5行数据。
1.2排序检索
1.2.1按单个列排序
select prod_name
from products
order by prod_name;
1.2.2按多个列排序
select prod_id, prod_price, prod_name
from products
order by prod_price, prod_name;
1.2.3按列序号进行排序
select prod_id,prod_price,prod_name
from products
order by 2,3;
Note
:在Sql注入中,经常使用这种方式进行数据表有多少列的判断。
1.2.4降序排序
select prod_id, prod_price, prod_name
from products
order by prod_price desc;
Note
order by 应该保证它是select语句中最后一条子句。
1.3过滤检索
1.3.1使用where子句
select prod_name,prod_price
from products
where prod_price = 3.49;
1.3.2where子句操作符号
- =
- !=
- <
- >
- <=
- >=
- between
- is null
1.3.3组合where子句
select prod_name,prod_price
from products
where vend_id = 'DLL01' or vend_id = 'BRS01' and prod_price >= 10;
1.3.4使用IN
select prod_name,prod_price
from products
where vend_id in ('DLL01','BRS01')
order by prod_name;
1.3.5使用LIKE
1%
表示任何字符出现任意次数
select prod_id,prod_name
from products
where prod_name like '%Fish%';
2_
只匹配单个字符
select prod_id,prod_name
from products
where prod_name like '__ inch teddy bear';
Note
通配符的搜索要耗费更长的处理时间
1.4处理检索
1.4.1创建计算字段
select prod_id,quantity,item_price,quantity*item_price as expanded_price
from orderitems
where order_num = 20008;
1.4.2聚集函数
select AVG(prod_price) as avg_price
from products;
select COUNT(*) as num_cust
from customers;
select max(prod_price) as max_price
from products;
select min(prod_price) as min_price
from products;
select sum(quantity) as items_ordered
from orderitems
where order_num =2005;
select count(*) as num_items, min(prod_price) as price_min,max(prod_price) as price_max,avg(prod_price) as price_avg
from products;
1.4.3分组数据
select vend_id,count(*) as num_prods
from products
group by vend_id;
select cust_id,count(*) as orders
from orders
group by cust_id
having count(*)>=2;
Note
having用于分组中的条件查询
1.4.4使用子查询
select cust_id from orders
where order_num in (select order_num from orderitems where prod_id = 'rgan01');
Note
先执行子查询,再执行外边的查询
1.4.5组合查询
union
将多个查询作为一个查询结果集返回,取多个查询的并集,并自动去除重复行
select cust_name,cust_contact,cust_email from customers
where cust_state in('IL','IN','MI')
union
select cust_name,cust_sontact,cust_emial from customers
where cust_name = 'Fun4All';
2其他操作
2.1插入数据
insert into customers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact,cust_email)
values ('100000006','Toy Land','123 Any Street','New york','NY','11111','USA',NULL,NULL);
2.2更新数据
update customers set cust_email = '[email protected]'
where cust_id = '100005';
2.3删除数据
delete from customers where cust_id = '100006';
2.4创建表
CREATE TABLE `tb_test`
(
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`en_name` VARCHAR(10) NULL DEFAULT '',
`ch_name` VARCHAR(10) NULL DEFAULT '',
`sex` VARCHAR(5) NULL DEFAULT '',
`school` VARCHAR(100) NULL DEFAULT '',
`age` DOUBLE(10,2) NULL DEFAULT '0.00',
`test3` VARCHAR(100) NULL DEFAULT '',
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci';
2.5删除表
drop table `tb_test`;
3扩展
3.1SQL执行顺序
from>join>on>where>*
group by>avg sum>having>
select>distinct>union>order by
Note
在给表起别名的时候,要放在from子句中
3.2联结表
3.2.1内联结
select vend_name,prod_name,prod_price from vendors,products
where vendors.vend_id = products.vend_id;
select vend_name,prod_name,prod_price
from vendors inner join products on vendors.vend_id = products.vend_id;
3.2.2外联结
外链接会包括没有关联的行。
比如:每个顾客下的订单进行计数,包括那些至今尚未下订单的顾客
select customers.cust_id,orders.order_num
from customers left join orders on customers.cust_id = orders.cust_id;
Note
左联结:左边是一个大表,右边是一个小表;以customers为基础填表,orders不足填空
select customers.cust_id,orders.order_num
from customers right outer join orders on orders.cust_id = customers.cust_id;
Note
以orders为基础,进行填表,不足补null
3.3视图
- 简化复杂的sql操作,在编写查询后,可以方便地重用它而不必知道其基本查询细节。
- 使用表的一部分而不是整个表。
- 视图实际上是一些逻辑上的组合表。
create view productcustomers as select cust_name,cust_contact,prod_id
from customers,orders,orderitems
where customers.cust_id=orders.cust_id and orderitems.order_num=orders.order_num;
3.4事务处理
为了保证数据的一致性
- 事务(transaction):指一组SQL语句。
- 回退(rollback):指撤销指定SQL语句的过程。
- 提交(commit):指将未存储的SQL语句结果写入数据库表。
- 保留点(savepoint):事务可回退的时间点。
begin transaction
...
commit transaction
Note
SQL Server的一种写法
3.5约束
3.5.1主键
3.5.2外键
外键必须为另一个表中的主键
外键的用途是确保数据的引用完整性。它通常包括以下几种:
- 实体完整性,确保每个实体是唯一的(通过主键来实施)
- 域完整性,确保属性值只从一套特定可选的集合里选择
- 关联完整性,确保每个外键或是NULL(如果允许的话)或含有与相关主键值相配的值
“外键”约束的主要目的是控制存储在外键表中的数据,但它还可以控制对主键表中数据的修改。例如,如果在 publishers表中删除一个出版商,而这个出版商的ID在titles表中记录书的信息时使用了,则这两个表之间关联的完整性将被破坏,titles表中该出版商的书籍因为与publishers表中的数据没有链接而变得孤立了。
外键约束防止这种情况的发生。如果主键表中数据的更改使之与外键表中数据的链接失效,则这种更改是不能实现的,从而确保了引用完整性。
如果试图删除主键表中的行或更改主键值,而该主键值与另一个表的外键约束值相关,则该操作不可实现。若要成功更改或删除外键约束的行,可以先在外键表中删除外键数据或更改外键数据,然后将外键链接到不同的主键数据上去。
外键是用来控制数据库中数据的数据完整性的,就是当你对一个表的数据进行操作和他有关联的一个或更多表的数据能够同时发生改变。这就是外键的作用。
3.5.3唯一约束
保证数值只出现一次
3.5.4检查约束
保证数值满足一组指定的条件
3.6索引
可以给被建立索引的字段进行恰当的排序,以加强搜索常用列的效率。
3.7触发器
为某些操作,指定一些特定的方法,当执行这些操作的时候,就会触发方法。
3.8关系型数据库设计原则
- 相同的数据出现多次决不是一个件好事,这是关系数据库设计的基础。
- 一类数据一个表,各表通过某些共同的值相互关联。(这就是关系数据库)
分开存放的好处:
- 相同的信息不会重复出。
- 在变更信息的时候,只需要修改一个地方就可以了。
- 由于数据不重复,数据一致好保证。