Mysql常用技巧总结

来源:互联网 发布:中山大学网络不好 编辑:程序博客网 时间:2024/05/22 07:01

最近大量使用Mysql, 需要对mysql大量技术进行总结。
这篇日志用来记录一些常用的技巧, 所以将持续更新。

1. 有时候我们需要统计数据库中某个字段的不同值出现的次数,比如users表中有个字段是country,我们想知道不同country的人有多少个,该怎么办呢?
可以这样做:SELECT distinct country, count(*) FROM `users` group by country order by count(*) desc

2. 如何将一个Sql文件导入本地的数据库?
常用的方法是: source + sql文件名 + 数据库名, 但是这种方法似乎在导入较大容量的sql文件时不是很有效。
可以采用这种方式:mysql -u管理员账号 -p密码 db_name<sql_file.sql   <表示重定向, 将sql_file.sql这个文件重定向到本地创建的数据库db_name中

3. Join | Inner join等用法:
Table A
aid   adate 
1      a1 
2      a2 
3      a3
 
Table B 
bid   bdate 
1      b1 
2      b2 
4      b4 

两个表a,b相连接,要取出id相同的字段 
select * from a inner join b on a.aid = b.bid这是仅取出匹配的数据. 
此时的取出的是: 
1 a1 b1 
2 a2 b2 
 
那么left join 指: 
select * from a left join b on a.aid = b.bid 
首先取出a表中所有数据,然后再加上与a,b匹配的的数据 
此时的取出的是: 
1 a1 b1 
2 a2 b2 
3 a3 空字符 
 
同样的也有right join 
指的是首先取出b表中所有数据,然后再加上与a,b匹配的的数据 
此时的取出的是: 
1 a1 b1 
2 a2 b2 
4 空字符 b4
 
LEFT JOIN 或 LEFT OUTER JOIN

左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值

FULL Join

取出两边出现过的行, 即使没有匹配

此时取出的结果是:

1 a1 b1 
2 a2 b2 

3 a3  空

4 空  b3


4 Distinct

有的时候取出的数据包含重复, 现在只需要不重复的所有的数据怎么办? 用distinct

比如:select distinct name from member w inner join task r on w.id = r.master_id;


5 inner join是可以联结多张表(3张以上)进行一次查询的

select w.* from receive_user w inner join message_receive_user r on w.status = 1 and w.receiver_id = 10 and r.receive_user_id = w.id
 inner join message p on r.message_receive_users_id = p.id and p.status = 2;

这条sql语句用了两个inner join 来连接3张表


6 有时候我们需要分页查询某一页的数据, 但是首先要知道一共有多少数据才能知道分页的时候有多少页, 这个时候往往需要两次连接数据库, 一次查询总次数, 一次用limit查询。。这样挺浪费资源的, 有没有办法可以做一次查询呢? 有的, mysql中 SQL_CALC_FOUND_ROWS就可以消除limit的影响, 得到根据limit之前条件查询出来的总条数, 以我写过的SQL语句为例:

sqlStr = select SQL_CALC_FOUND_ROWS w.* from msg_send w inner join msg_receive r inner join msg_contact_method p on p.member_id = @memberId and p.user_type = @userType and r.receiver_id = p.id and r.msg_send_id = w.id and r.read_status = @unreadStatus and w.send_status = 1 and r.is_delete = 0;

sqlStr += " limit " + Convert.ToString((pageNumber - 1) * pageSize) + "," + Convert.ToString(pageSize) + ";";
sqlStr += "select FOUND_ROWS()";

这样就可以用两条并在一起的sql语句一次查询获取所有想要的数据


7 一个重要的问题:如果根据表中的某个字段选择性的联结不同的表进行联合查询?

比如:我现在有A,B,C两张表, A表中有字段D, 现在的情况是:如果D=1,就去联合查询B表的数据, D=2就去联合查询C表的数据, SQL语句该怎么写?



8 Mysql多关键字查询

常常需要按照多关键字查询来获得某个既定的序列, SQL语句中的排序规则与大多数数据结构的排序规则都是一样, 先按第一关键字排序, 往后类推(还记得稳定排序中的多关键字排序对排序的影响么)

比如:select w.* from msg_send w inner join msg_receive r on r.msg_send_id = w.id and r.receiver_id = 1 and w.group_id <> 0 order by w.date_create desc, w.group_id asc;  这里就会首先按照w中的date_create关键字降序排序, 然后再按照w中的group_id关键字升序排序


9 关于联合查询时, 剔除那些在表中已经出现的数据

使用 not in,举个栗子:

select x.id, y.name, y.department_id from msg_contact_method x inner join member y on x.member_id = y.id where (x.member_id)
 not in (select r.member_id from msg_address_book w inner join msg_contact_method
 r on w.address_book_owner = @memberId and w.receiver = r.id and r.user_type = 1);


10 一边select一边进行update的正确姿势:

update msg_contact_method w inner join msg_address_book r on w.id = r.receiver set r.receiver_name = w.member_info

0 0
原创粉丝点击