in 和 exists的区别
- 子小主大用in: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in;
- 子大主小用exists:如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。
其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键)
- 如果是in,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 ,另外IN时不对NULL进行处理。
- 如果是exists,那么以外层表为驱动表,先被访问;
一直以来认为exists比in效率高的说法是不准确的。
- in 是把外表和内表作hash 连接;
- exists是对外表作loop循环,每次loop循环再对内表进行查询。
not in 和not exists的区别
- 如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
- 而not extsts 的子查询依然能用到表上的索引。
- 所以无论哪个表大,用not exists都比not in要快。
聚合函数中的 group_concat()
group_concat(x[,y])
该函数返回一个字符串,该字符串将会连接所有非NULL的x值。该函数的y参数将作为每个x值之间的分隔符,如果在调用时忽略该参数,在连接时将使用缺省分隔符","。再有就是各个字符串之间的连接顺序是不确定的。
注意:group_concat()函数要和group by语句同时使用才能产生效果!
select DepID,group_concat(StaffNames) from tablename group by DepID
参考:
SQLite 聚合函数中的 group_concat() - 狼族小子的专栏 - CSDN博客
https://blog.csdn.net/langzxz/article/details/16807859
drop、delete和truncate
相同点:drop、delete、truncate 都是删除表的内容。
不同点:
drop:删除表内容和结构,释放空间,没有备份表之前要慎用;
truncate:删除表的内容,表的结构存在,可以释放空间,没有备份表之前要慎用;
delete:删除表的内容,表的结构还存在,不释放空间,可以回滚恢复;
执行速度:
drop > truncate > delete
TOP, LIMIT, ROWNUM
sql server:top
SELECT TOP number|percent column_name(s)
FROM table_name;
mysql:limit
Limit子句可以被用于强制 SELECT 语句返回指定的记录数。Limit接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。
//初始记录行的偏移量是 0(而不是 1):
SELECT * FROM table LIMIT 5,10; //检索记录行6-15
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:
SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last
//如果只给定一个参数,它表示返回最大的记录行数目。换句话说,LIMIT n 等价于 LIMIT 0,n:
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
应用:分页的优化——给翻页提供一些线索
比如还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是1020,最小的是1000
SELECT * FROM message WHERE id>1020 ORDER BY id ASC LIMIT 20;//处理下一页
SELECT * FROM message WHERE id<1000 ORDER BY id DESC LIMIT 20;//处理上一页
oracle:rownum
ROWNUM是一个虚假的列。它将被分配为 1,2,3,4,…N,N 是行的数量。注意:
- 一个ROWNUM值不是被永久的分配给一行 。
- ROWNUM值的分配是在查询的谓词解析之后,任何排序和聚合之前进行的。ROWNUM值只有当被分配之后才会增长。这就是为什么下面的查询永远都不会返回结果:
select * from countries where rownum>1;//错误!
ROWNUM > 1对于第一行来说并不是真值,ROWNUM没有增长到 2。所以,没有比1大的ROWNUM。永远都不要使用’ROWNUM>?‘和’ROWNUM=2…N’这样的条件。
SELECT column_name(s)
FROM table_name
WHERE ROWNUM <= number;
通配符
% 替代一个或多个字符
_ 仅替代一个字符
[charlist] 字符列中的任何单一字符
[^charlist]或者[!charlist] 不在字符列中的任何单一字符
MySQL 中使用 REGEXP 或 NOT REGEXP 运算符 (或 RLIKE 和 NOT RLIKE) 来操作正则表达式。
参考:MySQL中REGEXP正则表达式使用大全 - t6 - 博客园
https://www.cnblogs.com/timxgb/p/5882742.html
in和=
相同点:均在WHERE中使用作为筛选条件之一、均是等于的含义
不同点:IN可以规定多个值,等于规定一个值
select * from Websites where name in ('Google','菜鸟教程');
select * from Websites where name='Google' or name='菜鸟教程';
between
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。反之,用NOT BETWEEN。
SELECT * FROM Websites WHERE alexa NOT BETWEEN 1 AND 20;
SELECT * FROM Websites WHERE name NOT BETWEEN 'A' AND 'H';
SELECT * FROM access_log WHERE date BETWEEN '2016-05-10' AND '2016-05-14';
join
SQL join 用于把来自两个或多个表的行结合起来。
下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。
on 和 where
在使用 join 时,on 和 where 条件的区别如下:
1、 on 条件是在生成临时表时使用的条件,它不管 on 中的条件是否为真,都会返回左边表中的记录。
2、where 条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有 left join 的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
UNION 和UNION ALL
-
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
-
默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
-
使用UNION命令时需要注意,只能在最后使用一个ORDER BY命令,是将两个查询结果合在一起之后,再进行排序!绝对不能写两个ORDER BY命令。
select aa.* from
(select country,name from websites where country = 'CN'
union all select country,app_name from apps where country='CN' ) aa
order by aa.name;
复制表 select into from 和 insert into select
两者的主要区别为: select into from 要求目标表不存在,因为在插入时会自动创建;insert into select from 要求目标表存在。
create table table_name_new as select * from table_name_old;// 复制表结构及其数据
create table table_name_new as select * from table_name_old where 1=2; //只复制表结构
insert into table_name_new select * from table_name_old //只复制表数据
insert into table_name_new(column1,column2...) select column1,column2... from table_name_old//只复制表数据
注意:MySQL 数据库不支持 SELECT … INTO 语句,但支持 INSERT INTO … SELECT 。可以使用以下语句来拷贝表结构及数据:
CREATE TABLE 新表
AS
SELECT * FROM 旧表
create
创建数据库
CREATE DATABASE dbname;
创建数据表
CREATE TABLE Persons
(
Id_P int NOT NULL PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255) ,
Address varchar(255),
City varchar(255)
)
alter
alter table x modify column_name not null;