id | name | age |
---|---|---|
1 | tom | 16 |
jack | ||
roles | 18 |
如上表:
count(age)=2;(计算age字段值不为空的记录数)
count(*)=3;(计算只要有一个字段值不为空的记录数)
count(1)=1;(计算第一个字段值不为空的记录数)
所以,这也是为什么count(1)的速度要比count(*)快的原因。因为count(1)只需要计算第一列就好了。
id | status |
---|---|
1 | 5 |
2 | 10 |
3 | 15 |
4 | 10 |
sql:
select count(if(e.status = 5,1,null)) as '状态为5的数量', count(if(e.status = 10,1,null)) as '状态为10的数量'from employee e;
sql解析:计算状态为5的数量;
count(if(e.status = 5,1,null)) 意思是:如果状态等于5,那么返回1,否则返回null
结果:
状态为5的数量 | 状态为10的数量 |
---|---|
1 | 2 |
ps:其实还可以这样:if中加or
select count(if(e.status = 5,1,null)) as '状态为5的数量', count(if(e.status = 10 or e.status = 15,1,null)) as '状态为10或15的数量'from employee e;
表:
id | name | salary |
---|---|---|
1 | tom | 6000.00 |
2 | jack | 7000.00 |
3 | roles | 6000.00 |
sql | 解析 |
---|---|
count(distinct(id)) | 返回id不同的记录数 |
select distinct name from user | 返回name不同的记录 |
select distinct id,name from user | 过滤id和name都重复的记录 |
如上,第二第三条语句只会返回过滤的字段值,啥意思呢?
就是第二条sql只会显示name字段,第三条sql只会显示id,name字段。
有的时候我们既要按照要求过滤重复记录,又要显示所有的字段该怎么办呢?有的时候我们既要按照要求过滤重复记录,又要显示所有的字段该怎么办呢?这个时候我们一般可以使用group by分组来达到去重的效果。
需求:按照salary去重,同时显示其他字段。
解析:select * from employee where id in (select max(id) from employee group by salary);
这样就可以达到我们的目的啦!
当我们在测试的时候想要插入大量数据怎么办?使用JDBC在java中for循环?麻烦!
直接在sql使用存储过程插入就好啦。
例:
DROP PROCEDURE if exists insertdata;
delimiter //
CREATE PROCEDURE insertdata()
begin
declare num int;
set num=1;
while num < 1000000 do
insert into tabless (id,title, tel) values(num,concat("title", num),concat("134", num));
set num=num+1;
end while;
end//
delimiter;
call insertdata();
主要sql解析:
行号 | 解析 |
---|---|
1 | 如果insertdata程序存在则删除(注意:如果PROCEDURE名字一样,则每次使用都要删除掉之前的PROCEDURE,否则报错) |
2 | 定界符,sql中是以’;'结尾的,遇到;表示这条语句已经到此为止了。delimiter //的作用就是告诉myslq解释器,遇到// 才表示此语句到此为止。 |
3 | 创建一个名为:insertdata 的 PROCEDURE |
5 | declare 声明字段类型 |
最后一行 | call 调用存储过程,就相当于java调用方法一样(可以这样理解) |
我们都知道Redis中有5中数据类型:string、list、set、hash、zset;殊不知,Redis中还可以存放字节类型的数据,还可以设置key为自增长。
我们使用RedisTemplate就是将数据装换成字节然后再存储到Redis中的。
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.incrementAndGet();
使用RedisAtomicLong类获取key的自增值,incrementAndGet()方法是先自增再获取,也有先获取再自增的方法getAndIncrement();这两个方法就相当于是++i与i++一样。
参数1:key;参数二:redis连接工厂。
也可以按照一定的步长自增:
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.addAndGet(num);//自增量,比如一次自增2
自己写的工具类RedisService.java中的方法:
/**
* 设置对象
* @param key
* @param object
* @param expireTime 失效时间:null 永不失效/不修改剩余失效时长;其他数值表示失效时长(秒)
* @return
*/
public <K> void setData(String key, K object, Integer expireTime){
ValueOperations<String, K> option = redisTemplate.opsForValue();
if(expireTime!=null) {
// 设置数据
option.set(key, object);
// 设置失效时间
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
} else {
// 删除数据
redisTemplate.delete(key);
// 设置数据
option.set(key, object);
}
}
Redis中有三种删除过期数据的方式。
方式一:立即删除;但是这样会存在一个问题,就是:如果这个时候CPU很忙,而同时间过期的数据又不少,这样就更加的增加了CPU的负担;
方式二:懒惰删除;到了过期时间不立即删除,而是等下次用到的时候再查询该数据的过期时间,如果过期则删除;
方式三:定时删除;
Redis是方式二和方式三结合使用。
以前一直觉得我们在配置文件中指定了在哪个数据库就只能在哪个数据库做操作,后面发现只要能够连接上myslq的服务就可以对服务上的所有的数据库做操作,尽管我们程序的配置文件不是指定的该数据库也可以。
cabinet-other库 | cabinet-system库 |
---|---|
bas_case_type表 | bus_operation_record表 |
bas_res表 | bus_cabinet_landing表 |
bas_res_details表 |
如上:两个数据库、共5张表
sql:
select count(DISTINCT(rd.res_id)) from `cabinet-other`.bas_case_type ct
INNER JOIN `cabinet-other`.bas_res r on ct.identifying=r.types_of_cases
inner JOIN `cabinet-other`.bas_res_details rd on rd.res_id=r.id
INNER JOIN `cabinet-system`.bus_operation_record ord on ord.epcid=r.epcid
inner join `cabinet-system`.bus_cabinet_landing clg on clg.id = ord.cabinet_landing_code
where r.delete_flag='0' AND ord.flag='0'
跨库查询,只需要在原本的表名之前加上数据库的名称就可以了…
try {
// 获取分布式锁
Boolean lock = redisTemplate.opsForValue().setIfAbsent("kill_" + id, true);
if(lock) {// 获取锁成功
// 业务逻辑...
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally { // 释放分布式锁(避免死锁)
redisTemplate.delete("kill_" + id);
}
myslq 中 union 与 union all 都是用来将多个结果集合并成一个结果集。
例:
表1:
id | name |
---|---|
1 | jack |
2 | tom |
表2:
id | name |
---|---|
1 | jack |
2 | roles |
使用UNION 合并的结果是:UNION会自动压缩结果中的重复结果,同时进行默认规则的排序。
id | name |
---|---|
1 | jack |
2 | tom |
3 | roles |
使用UNION ALL合并的结果是:UNION ALL则是将全部的结果都展示出来,不管有没有重复,不进行排序。
id | name |
---|---|
1 | jack |
2 | tom |
3 | jack |
4 | roles |
ps:使用union和union all必须保证各个select
集合的结果有相同个数的列,并且每个列的类型是一样的。但列名则不一定需要相同,oracle会将第一个结果的列名作为结果集的列名。mysql中应该也是一样的
function isJSON(str) {
if (typeof str == 'string') {
try {
var obj=JSON.parse(str);
if(typeof obj == 'object' && obj ){
return true;
}else{
return false;
}
} catch(e) {
console.log('error:'+str+'!!!'+e);
return false;
}
}
console.log('It is not a string!')
}