先使用题目进行引入
1.某网站商品的购买订单表为orders,结构如下:
id 子增id
user_id 购买者id
product_id 商品id
time 购买时间
price 订单总价
创建表语句
create table orders(
id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
user_id int(11) NOT NULL COMMENT '购买者ID',
user_id int(11) NOT NULL COMMENT '商品ID',
price decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '价格',
add_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_time (time)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表';
主键也可以写到上面,primary_key就不用使用not null了
create table orders(
id int(11) unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 'id',
user_id int(11) NOT NULL COMMENT '购买者ID',
user_id int(11) NOT NULL COMMENT '商品ID',
price decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '价格',
add_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY idx_time (time),
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表';
统计sql语句
1.找出销量大于1000的商品,按销量排序,销量高的在前
select product_id from orders as o group by o.product_id having count(*) > 1000 order by count(*) desc;
如果还需要知道销量那么:
select o.product_id,count(*) from orders as o group by o.product having count(*) > 1000 order by count(*) desc;
count计算的是行数,跟传字段名没有关系
2.找出消费最多的10个用户
select user_id from orders as o group by o.user_id order by sum(price) desc limit 10;
2.对于sql中使用到的进行分析
select子句使用顺序:select from where group by having order by limit
where : 写条件对结果进行过滤
group by :
后面可以跟随多个列名,对后面跟随的列名进行分组,然后对每一个分组而不是整个表进行操作
如果后面跟了多个列名就是嵌套,则数组将在最后一个分组上进行汇总
除了聚集语句外,SELECT语句中的每一个列都必须在GROUP BY子句中给出
如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多个NULL,它们将作为一个分组返回
having:
因为where子句是针对行的过滤,用户过滤结果。要对分组结果进行过滤必须使用having子句。
order by : 排序,desc降序 asc 升序,默认为asc ,可以按统计函数的结果进行排序
3.having和where的区别
区别一:
where 是数据从磁盘读入内存时候一条一条判断的
having 是将所有数据读入内存,在分组统计前,根据having的条件再将不符合条件的数据删除
区别二:
having 子句可以使用字段别名,where不可以用
区别三:
having可以使用统计函数,where不可用
having筛选必须是 根据前面select字段的值 进行筛选,就像上述的sql中必须对product_id进行select,否则会报错
注意:where 后面要跟的是数据表里的字段,如果我把ag换成avg(price)也是错误的!因为表里没有该字段。而having只是根据前面查询出来的是什么就可以后面接什么。
例如:
1)select category_id , avg(price) as ag from dw_goods group by goods_category having ag > 100
2)select category_id , avg(price) as ag from dw_goods where ag>100 group by goods_category //报错!!因为from dw_goods 这张数据表里面没有ag这个字段