接到了一个新的需求,拿到需求的时候瞬间有点头大,因为实在是有些棘手。

我们这个系统本身是个接口系统,总接口数大概在200个左右。外部会有很多用户在

不同的时间拿着不同参数去调我们的这些接口,用户的调集记录会写在数据库的一个

日志表里。日志表字段大概有url(带参数),用户id,调用时间,返回结果等等等

等。现在的需求是,查询一定时间范围内(12月)里,同一个用户在7天之内调用的

接口url和时间。

麻烦的是接口url本身比较复杂。它的长度大约在200-500,里面有几个麻烦的参数:

一个是时间戳,时间戳有可能是传递,也有可能是生成的,它铁定不重复。另一个是

数字签名,它会根据参数和时间戳通过算法生成,也铁定不重复。所以解决这个问题

的第一步,是把url进行处理。去掉这两个铁定不重复的参数。
这个系统还有个让人蛋疼的地方,就是它是两个系统合二为一的。两个系统的时间戳

和数字签名参数名称是不一样的,也就是说有四个参数需要判断是否存在+处理。这

一步肯定是用函数做。新建函数如下:

CREATE FUNCTION ReplaceUrl (strUrl varchar(800))
RETURNS varchar(800)
BEGIN
DECLARE v_Tmp_1 varchar(800) default '';
DECLARE v_Tmp_2 varchar(800) default '';
DECLARE v_Tmp_3 varchar(800) default '';
DECLARE v_Tmp_4 varchar(800) default '';

SET v_Tmp_1 = if(locate('timeStamp',strUrl)>0,REPLACE

(strUrl,SUBSTRING_INDEX(SUBSTRING_INDEX(strUrl,'timeStamp',-

1),'&',1),''),strUrl);
SET v_Tmp_2 = if(locate('time_stamp',v_Tmp_1)>0,REPLACE

(v_Tmp_1,SUBSTRING_INDEX(SUBSTRING_INDEX(v_Tmp_1,'time_stamp',-

1),'&',1),''),v_Tmp_1);
SET v_Tmp_3 = if(locate('access_signature',v_Tmp_2)>0,REPLACE

(v_Tmp_2,SUBSTRING_INDEX(SUBSTRING_INDEX(v_Tmp_2,'access_signature',-

1),'&',1),''),v_Tmp_2);
SET v_Tmp_4 = if(locate('accessSignature',v_Tmp_3)>0,REPLACE

(v_Tmp_3,SUBSTRING_INDEX(SUBSTRING_INDEX(v_Tmp_3,'accessSignature',-

1),'&',1),''),v_Tmp_3);
RETURN v_Tmp_4;
END;

MYSQL中if函数使用方法是if(参数1,参数2,参数3),如果参数1正确则执行参数2,

不正确执行参数3。这里先判断url是否含有参数A,如果含有则执行替换,不含有则

什么都不处理。
替换的逻辑是REPLACE函数,REPLACE(参数1,参数2,参数3),参数1是等待执行的

参数,参数2是被替换的字段,参数3是替换为的字段。我们把指定参数替换为空就可

以了。
里面还有个参数是SUBSTRING_INDEX——按关键字截取字符串,用法是

substring_index(被截取字段,关键字,关键字出现的次数),次数为正是往右数

,次数为负是往左数。我们直接把次数设置为-1,也就是参数分隔符&左边的该参数

全部被截取就可以了。

连续执行4次之后,url的四个随机生成参数全部被清除,可以执行查重了。

第二步,排重。
难的不是排重,而是排重之后还要加上7天检索的算法。问题可以简化为,有一张表

,表里只有3个字段,id,name,time。现在要检索重复的name,还要加上time必须在

7天之内,否则就不算重复。
那么答案是:

select t1.* from table_name t1 join table_name t2 on t1.name=t2.name and

t1.id!=t2.id
where abs(t1.time-t2.time)<=7

这是一张表当两张表关联查询,虽然我知道会很慢,目前也没有更好的办法能解决这

个问题。

那么,这个问题最终的解决语句是,新建函数——将范围内的日志调取出来新建表——把新表处理后的url执行md5——再查重

CREATE FUNCTION ReplaceUrl (strUrl varchar(800))
RETURNS varchar(800)
BEGIN
DECLARE v_Tmp_1 varchar(800) default '';
DECLARE v_Tmp_2 varchar(800) default '';
DECLARE v_Tmp_3 varchar(800) default '';
DECLARE v_Tmp_4 varchar(800) default '';

SET v_Tmp_1 = if(locate('timeStamp',strUrl)>0,REPLACE(strUrl,SUBSTRING_INDEX(SUBSTRING_INDEX(strUrl,'timeStamp',-1),'&',1),''),strUrl);
SET v_Tmp_2 = if(locate('time_stamp',v_Tmp_1)>0,REPLACE(v_Tmp_1,SUBSTRING_INDEX(SUBSTRING_INDEX(v_Tmp_1,'time_stamp',-1),'&',1),''),v_Tmp_1);
SET v_Tmp_3 = if(locate('access_signature',v_Tmp_2)>0,REPLACE(v_Tmp_2,SUBSTRING_INDEX(SUBSTRING_INDEX(v_Tmp_2,'access_signature',-1),'&',1),''),v_Tmp_2);
SET v_Tmp_4 = if(locate('accessSignature',v_Tmp_3)>0,REPLACE(v_Tmp_3,SUBSTRING_INDEX(SUBSTRING_INDEX(v_Tmp_3,'accessSignature',-1),'&',1),''),v_Tmp_3);
RETURN v_Tmp_4;
END;

CREATE TABLE api_table (
SELECT ReplaceUrl(T5)
as temp,T1,DATE(T6) as daytemp,T5,T6
FROM
`v2-api-log`WHERE DATE(t6) BETWEEN '2017-11-24' AND '2017-12-24')

alter table api_table add column md5temp varchar(50);
UPDATE api_table set md5temp = MD5(temp);
ALTER TABLE api_table ADD INDEX tempindex (md5temp);

create table api_repeat(
SELECT
t1.temp,t1.T1,t1.T6
FROM
api_table t1
JOIN api_table t2 ON t1.md5temp = t2.md5temp
AND t1.T1 = t2.T1
AND t1.T6 != t2.T6
WHERE
abs(t1.daytemp - t2.daytemp) <= 7
GROUP BY T6)

《MYSQL》----字符串的复杂函数,检索的七-天-排-重的更多相关文章

  1. MySQL 字符串截取SUBSTRING()函数

    MySQL 字符串截取相关函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例: select left(content,200) as ab ...

  2. MySQL 字符串连接CONCAT()函数

    MySQL字符串连接函数 使用方法:CONCAT(str1,str2,-) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. 注意:如果所有参数均为非二进制字符串, ...

  3. mysql字符串的常用函数(截取和拼接)

    #截取字符串(先正序取2个,再倒序取1个)SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('aaa-gg-cc-dd','-',2),'-',-1) #获取子表某个字段的 ...

  4. 025、MySQL字符串大小写转化函数,文本转化大写,文本转化小写

    #变大写 SELECT UPPER('abcdABCD123a'); #ABCDABCD123A SELECT UCASE('abcdABCD123a'); #ABCDABCD123A #变小写 SE ...

  5. MySQL字符串函数substring:字符串截取

    MySQL 字符串截取函数:left(), right(), substring(), substring_index().还有 mid(), substr().其中,mid(), substr() ...

  6. Mysql字符串截取函数SUBSTRING的用法说明

    感觉上MySQL的字符串函数截取字符,比用程序截取(如PHP或JAVA)来得强大,所以在这里做一个记录,希望对大家有用. 函数: 1.从左开始截取字符串 left(str, length) 说明:le ...

  7. MySQL字符串函数

    字符串大写和小写转换 MySQL 字符串大写和小写转化函数有两对: lower(), uppper() 和 lcase(), ucase() mysql> select lower('DDD') ...

  8. mysql字符串连接,重复等字符串函数总结

    mysql concat()函数 MySQL的concat函数可以连接一个或者多个字符串,如 select concat('10'); 输出 10 select concat('11','22','3 ...

  9. MySQL字符串函数、日期时间函数

    MySQL字符串函数.日期时间函数 一.常见字符串函数: 1.CHAR_LENGTH  获取长度(字符为单位) 2.FORMAT  格式化 3.INSERT  替换的方式插入 4.INSTR  获取位 ...

随机推荐

  1. TCP/IP协议栈 ARP和RARP协议

    上几章中我们提到以太网协议中,在以太网首部中一个帧类型的字段,它可以表示为IP ARP RARP协议. 这里说一下ARP 和RARP协议. 首先看ARP协议: 要想网络中的数据包准确到达某个主机,最后 ...

  2. 【jQuery插件】使用cropper实现简单的头像裁剪并上传

    插件介绍 这是一个我在写以前的项目的途中发现的一个国人写的jQuery图像裁剪插件,当时想实现用户资料的头像上传功能,并且能够预览图片,和对图片进行简单的裁剪.旋转,花了不少时间才看到了这个插件,感觉 ...

  3. CCF-201509-1-数列分段

    问题描述 试题编号: 201509-1 试题名称: 数列分段 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共 ...

  4. Undefined index: HTTP_RAW_POST_DATA的解决办法

    $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 替换为 $postStr = isset($GLOBALS['HTTP_RAW_POST_DA ...

  5. NGUI_Button

    十.按钮,Button 1.按钮的核心作用: 按钮能够接收单击并触发响应事件 按钮单击时能同时触发多个响应事件 按钮可以有普通.悬停.单击.禁用等多个状态的不同表现 广泛的说,按钮的核心在于接收事件 ...

  6. java 之 桥接模式(大话设计模式)

    桥接模式定义为:将抽象部分与它的实现部分分离,使它们都可以独立的变化. 第一次看设计模式的时候,不是很清楚这句话的意思,随着笔者的不断开发,发现有一种场景, 继承关系多了,不易于维护父类,而笔者认为桥 ...

  7. DDD实践

    一. 虽然招聘是主旋律,但技术还是得不断的突破.在.net core的实践中,一开始就瞄准了DDD.需要特别感谢https://github.com/EduardoPires/EquinoxProje ...

  8. Maven SpringMVC整合Mybatis

    关于Spring的核心理念和Mybatis的优点网上已经有很多文档做了说明.这篇博客,只记录springmvc整合mybatis时常见的知识点,以及注意事项,它只有最精简的几个模块,以帮助初学者迅速搭 ...

  9. Java-----关于线程池的使用

    关于线程的相关概念不在此阐述,请百度或谷歌之 对于学习线程来说,我认为从代码开始学习比较好,前提是有一定的技术的积累,否则请关闭不用再看了~ 线程池四种实现方式. ①可缓存线程池,如果线程池长度超过处 ...

  10. POJ 2631 Roads in the North(树的直径)

    POJ 2631 Roads in the North(树的直径) http://poj.org/problem? id=2631 题意: 有一个树结构, 给你树的全部边(u,v,cost), 表示u ...