主键可以是一个或者是多个列,但所有的列(或者是列的组合)必须是唯一的,非空的
关键字distinct 可以去重,实现该效果还可以使用group by
limit 默认从 0 开始,limit 5 其实是 limit 0 5 , 0 为起始行,5 为读取的数量。limit 命令要放在 group by 后面。
如:
select vend_id from products group by(vend_id) limit 0 5;从0开始,取 5行,一共5行
select disctinct vend_id from products limit 1 offset 3;从第1行开始计数,取第三行;一共就一行
select vend_id from products where vend_id > 1002 group by(vend_id) having vend_id >= 1003 order by vend_id desc limit 3;
字句顺序
select ... from ... where ... group by ... having ... order ... limit ...
where 字句 用于对数据库原始数据集进行筛选,而having 用于对经过group by以后的数据集进行筛选。
where 可用的条件操作符如下:
= != > < >= <= between and in not
空值 null 检测用 is ,不能用 =
select name from testnull where name is null;
select name from testnull where name is not null; √
select name from testnull where name not is null;× 这么查是错的
使用and 和 or 过滤数据
select prod_id,prod_name from products where vend_id = 1003 and prod_price <= 10;
and 且, 必须同时满足两个条件
select prod_id,prod_name from products where vend_id = 1003 or prod_price <= 10;
or 或 只要满足这两个条件其一即可。(注意,这并不代表会涵盖所有数据)
例如满足这个过滤条件的产品是这样的:
1.该产品的vend_id = 1003 ,无论 该产品的 价格是否<=10,即使 >10 也没关系
2.该产品的 vend_id != 1003 ,那么该产品必须 <= 10 才能入选,
所以:
对于那些 vend_id != 1003 的且 价格 > 10 的产品,他们是不符合条件的。
and or 的优先级:
and 和or 同时出现时,and 的优先级比or高,也就是说,where子句过滤条件会先执行and子句,然后在执行or子句。如果想改变这种执行顺序,主要讲or子句用() 包裹即可。
select * from products where vend_id = 1002 or vend_id =1003 and prod_price >10;
这句话中,要求产品符合如下条件之一即可:
1.vend_id = 1002 ,其他价格什么的随意,没有任何限制
2.vend_id = 1003 且 price>10 这两个 条件都满足的产品才会被选中
select * from products where (vend_id=1002 or vend_id = 1003) and prod_price >10;
这句话,要求产品符合如下条件:
1.产品 vend_id =1002 或者是 =1003,都可以
同时要求:
2.price>10
以上这两个条件同时满足才行。
也就是说:筛选 1002 ,1003 生产的所有 价格 >10 的产品。
in not 操作符
select * from products where vend_id in (1002,1003); 效果和 vend_id = 1002 or vend_id = 1003 一样;但是 in 后面可以包含其他的 select 子句。
select * from products where vend_id not in(1002,1003);
not 的作用是否定它后面所跟着的任何条件
select * from products where vend_id between 1001 and 1004;
select * from products where vend_id NOT between 1001 and 1004;
like _ % 通配符 regexp 正则表达式
% 表示 任意 数量的 任意 字符 _ 仅表示 一个 字符;
除了 NULL
select * from products where vend_id like '1__2'; 以 1开头的 2结尾的中间两个随意的厂商。
select * from products where vend_id like '%2';以2为结尾的所有厂商;
select * from products where prod_name regexp '100';名字中包含 1000 的产品。
注意
like 和 regexp 的不同点
select * from products where prod_name like '1000'; 结果为空
select * from products where prod_name regexp '1000';有结果
因为 like 匹配整个列,也就是说,所有列中,某一列为 1000才符合条件,才会被选中,此例中就是 说满足条件的是且只能是 1000,因为没用通配符,所以它只匹配自己。
而 regexp 是匹配每一列的值,只要该列的值满足条件,那么就可以。此例中要想达到like的效果,
需要如下改进 regexp '^1000$'
concat 拼接 ,被拼接对象之间用 , 分隔。
as 使用别名(又叫 导出列)
select concat(vend_name,'【',vend_country,'】') as name from vendors ;
结果
ACME【USA】
trim rtrim ltrim 去掉空格(左右两端空格,右边空格,左边空格)
select * from testnull where trim(name) = 'xi';
testnull 表中有一行数据 name = ' xi '
计算
select prod_id,quantity,item_price,quantity*item_price as expanded_price from orderitems;
对字符串进行操作
upper lower trim substring length
**substring(name,1,4) ** 三个参数
处理日期的函数
日期格式 yyyy-mm-dd (eg:2000-01-01)
adddate增加一个日期
addtime 增加一个时间
curtdate 返回当前日期
curtime 返回当前时间
year 返回日期的年部分
month 返回日期的月份部分
day 返回日期的天部分
hour 返回时间的时部分
minute 返回时间的分部分
second 返回时间的秒部分
date 返回日期时间的日期部分
time 返回日期时间的时间部分
now返回当前时间
datediff两个日期的时间差
date_format 返回一个格式化的日期或时间串
数值函数
abs绝对值
mod 余数
pi 圆周率
rand 随机数
sqrt 平方根
sin cos tan
聚集函数
avg 平均数
count 行数
max最大值
min最小值
sum 和
分组
group by
分组 的重要规定
1. group by 子句可以包含任意数目的列(虽然我们应该用一个)
2. 如果 group by 子句中嵌套了分组,那么数据最后规定的分组上进行汇总
3. group by 子句列出的每个列必须是检索列或有效的表达式(但不能是聚合函数).如果在select中使用了表达式,则必须在group by 子句中指定相同的表达式。不能使用别名
4. 除聚集函数外,select 语句中的每个列都必须在group by子句中给出(也就是说,select后面的字段,要么做聚集函数的参数,被聚集函数使用,要么就必须出现在grgoup by 子句中)
5. 如果分组中列具有NULL 值,那么NULL 将作为一个分组返回。如果含有多个NULL那么他们将作为一个分组。
6. group by 子句必须在 where 子句之后,order by 之前
having 过滤分组
having 类似 where 都具有筛选的作用,只是一个筛选组,一个筛选行
where 大部分子句都可以用于having
select vend_id from products where vend_id > 1002 group by(vend_id) having vend_id >= 1003 order by vend_id desc limit 3;
字句顺序
select ... from ... where ... group by ... having ... order ... limit ...
where 字句 用于对数据库原始数据集进行筛选,而having 用于对经过group by以后的数据集进行筛选。