Mysql 使用存储过程合并多个表数据

news2024/11/28 17:46:52

Mysql 使用存储过程合并多个表数据 

drop procedure if exists mergeTable;
CREATE PROCEDURE mergeTable()
BEGIN

    #定义变量
    declare temp_table_name varchar(20);
    declare total int default 0;
    declare done int default false;
    #游标数据来源  查询出你想要合并的表名称
    declare cur cursor for SELECT table_name
                           from information_schema.TABLES
                           where table_name LIKE '%user%'
                           group by table_name;
    #定义标记结束
    declare continue HANDLER for not found set done = true;

    drop table if exists temp_table;
    #创建临时表
    CREATE temporary TABLE `temp_table`
    (
        `id`   int(11)    NOT NULL,
        `name` int(11)    NOT NULL,
        `type` tinyint(2) NOT NULL
    );


    set total = 0;
    open cur;
    #变量赋值
    fetch cur into temp_table_name;
    while(not done)
        do
            #复制表数据到临时表
            set @sqlStr = CONCAT('INSERT INTO temp_table (`id`, `name`, `type`)
        SELECT `id`, `name`, `type`
     FROM  ', temp_table_name);

            PREPARE stmt from @sqlStr;
            #执行sql
            EXECUTE stmt;

            fetch cur into temp_table_name;
        end while;

    close cur;
    #统计临时表个数
    select count(1) from temp_table;
END;

#执行临时表
call mergeTable();

编写mysql存储过程,循环的查询到表结构相同的多张表记录并将结果表合并输出。可以查询多天也可查询单天

直接实例代码与注释

CREATE PROCEDURE tableData1(in sTime VARCHAR(255),in eTime VARCHAR(255))
BEGIN #创建传入两个参数的存储过程,sTime开始时间,eTime结束时间
        #定义变量
        DECLARE date VARCHAR(255);
        declare sqlVar varchar(21845);
        declare rest int;
        declare tableName varchar(1024);
        
        #给初始值 sqlVar为空字符串,因为下边要拼接sql语句
        set rest = 100;
        set sqlVar='';

#当开始时间等于结束时间时,只拼接一次sql语句-实现可以只查询一天数据
if sTime = eTime THEN
SET date = DATE_FORMAT(sTime,"%Y-%m-%d");
set sqlVar=CONCAT(sqlVar," (SELECT *
FROM data_detail_",sTime," WHERE XXX
 ");
 
 ELSE
        
#rest初始值是随便给的大于0的值。所以一定会进入循环。接下来在下边使用函数DATEDIFF用结束时间减去开始时间
#给rest重新赋值,当大于0时说明还没结束继续拼接sql,当等于或小于零时说明应该结束了,不需要继续往下拼接sql
while rest > 0 do
 
 #转换日期格式,根据您自己的表结构来改,我是需要的
 SET date = DATE_FORMAT(sTime,"%Y-%m-%d");
        
 #使用开始时间拼接上字符串成为表名
 set tableName=CONCAT('data_detail_',sTime);
 
 #查询是否存在当前表名,赋值个数给cnt
 select count(1) from information_schema.tables where table_name = tableName into @cnt;

 #判断表名是否存在,当表不存在时直接跳过,不判断的话会报错
 if @cnt != 0 then

 #最最最重要的一点,当结束时间减去开始时间为1时,需要走else拼接上后边的的union all 。
 #当结束时间减去开始时间为1时,说明已经到达结束时间的前一天,并且在最后DATE_ADD将前一天日期加1已经到达结束时间。最后不需要再拼接上一个union all
        if rest=1 then
         set sqlVar=CONCAT(sqlVar," (SELECT *
FROM data_detail_",sTime," WHERE XXX
)");
    ELSE
         set sqlVar=CONCAT(sqlVar," (SELECT
FROM data_detail_",sTime," WHERE XXX
)",' UNION all');
    END IF;
 END if;

#判断到达某日期,当rest为1时说明已经到达结束日期前一天
set rest = DATEDIFF(eTime,sTime);
#当前日期加1
set sTime = DATE_FORMAT(DATE_ADD(sTime,INTERVAL 1 day),'%Y%m%d');

#结束循环与判断
END while;
END if;
    
#赋值用户变量
set @v_s=sqlVar;
#预定义sql语句
prepare stmt from @v_s;
#执行预定义sql语句
EXECUTE stmt;
#释放资源
DEALLOCATE PREPARE stmt;
 
end;

 

call tableData1(‘20211006’,‘20211008’);
结果长这个样子

 

1.创建存储过程语法:
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一组合法的SQL语句)
END
2.变量的定义与赋值:
局部变量
DECLARE variable_name datatype(size) DEFAULT default_value;
DECLARE相当于关键字,有点类似var,表示定义一个变量;然后variable_name是你指定的变量名称;datatype表示数据类型而括号内的size表示对应类型的格式比如varchar(50)这样子,这里需要注意的是datatype只能是MySql支持的那些基本数据类型;DEFAULT关键字指明了变量的默认值为default_value。
通过SET赋值: SET variable_name = XXX
用户变量
用户变量不需要声明,可以直接使用,用户变量以@var_name的形式命名变量,变量名必须以@开头
赋值语法; set @varName=value;

只说了我用到的两种变量,其他变量查阅其他资料哦

3.While循环语句结构:
while(表达式) do

end while;
与其他语言while循环大同小异了其实,不难理解当表达式结果为false时退出循环
4.if判断语句:
IF expression THEN
statements;
ELSE
else-statements;
END IF;
5.union与union all 的区别
对重复结果的处理:UNION在进行表链接后会筛选掉重复的记录,Union All不会去除重复记录
 

 

     需求: A库有多张按时间分表创建的表a_table_${date},我想用定时器每天凌晨在B库创建一张和A库昨天的表一样的表b_table_${date},然后将数据抓取过来,然后再对同步过来的表b_table_${date}做一次统计汇总插入到B库的另一张表b_table_statistic中。 使用存储过程做。可以根据统计时间传参来同步不同时间的数据。

          思路:

               1. 如果B库不存在统计日期的表b_table_${date}则创建一个新表b_table_${date};

               2. 开启事务,将B库表b_table_${date}的数据清空,方便失败了再次统计;

               3. 将A库a_table_${date}表的数据同步到B库b_table_${date}表;

                   注意: 在插入的时候如果数据量比较大,可以通过分组进行批量插入来避免事务问题和mysql插入数据量限制问题;

               4. 先删除B库b_table_statistic表中统计日期的数据;然后再向B库b_table_statistic表中插入统计日期的统计数据;

               5. 关闭事务;
二. sql建模
三. 脚本

     
    -- statistic_date 统计日期  接收yyyy-MM-dd类型的时间字符串
    CREATE PROCEDURE create_current_day_cdr_table (IN statistic_date VARCHAR(64)) BEGIN
        
        -- 同步t_cdr表记录需要插入的次数
        DECLARE CDR_TABLE_INSERT_COUNT INT;
        
        -- 声明事务
        DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING ROLLBACK ;
     
        -- 每次插入的记录数
        SET @EACH_INSERT_SIZE = 1000;
        
        -- 循环变量
        SET @i = 1;
        
     
        -- 根据统计日期拼接话单详情表名称
        SET @tableName = CONCAT("t_cdr_", from_unixtime( unix_timestamp(statistic_date), '%Y%m%d') );  
     
     
        -- 如果统计日期的话单详情表不存在则创建
        SET @createTableStr = CONCAT(" CREATE TABLE IF NOT EXISTS ", @tableName , "(
                        `id` int(11) NOT NULL AUTO_INCREMENT,
                        `call_type` char(2) DEFAULT NULL COMMENT '通话类型',
                        `cb_sessionid` varchar(64) DEFAULT NULL,
                        `busiprefix` varchar(16) DEFAULT NULL,
                        `caller_brand` varchar(64) DEFAULT NULL COMMENT '主叫品牌',
                        `caller` varchar(64) DEFAULT NULL COMMENT '主叫号码',
                        `calleraccess` varchar(64) DEFAULT NULL COMMENT '呼入主叫',
                        `callee_brand` varchar(64) DEFAULT NULL COMMENT '被叫品牌',
                        `callee` varchar(64) DEFAULT NULL COMMENT '被叫号码',
                        `calleeaccess` varchar(64) DEFAULT NULL COMMENT '呼入被叫',
                        `calleeoriginal` varchar(64) DEFAULT NULL COMMENT '被叫裸号',
                        `callerip` varchar(64) DEFAULT NULL COMMENT '主叫IP',
                        `in_gw_media_ip` varchar(64) DEFAULT NULL COMMENT '主叫媒体IP',
                        `in_gw_media_isp` int(11) DEFAULT NULL,
                        `callergatewayh323id` varchar(512) DEFAULT NULL COMMENT '主叫经由网关',
                        `callerproductid` varchar(64) DEFAULT NULL COMMENT '主叫设备',
                        `callertogateway` varchar(64) DEFAULT NULL COMMENT '呼出主叫',
                        `calleeip` varchar(64) DEFAULT NULL COMMENT '被叫信令IP',
                        `calleegatewayh323id` varchar(64) DEFAULT NULL COMMENT '被叫经由网关',
                        `calleeproductid` varchar(128) DEFAULT NULL COMMENT '被叫设备',
                        `calleetogateway` varchar(64) DEFAULT NULL COMMENT '呼出被叫',
                        `rtp_ip` varchar(64) DEFAULT NULL COMMENT '被叫媒体IP',
                        `gd_gw_media_isp` int(11) DEFAULT NULL,
                        `billingmode` char(1) DEFAULT NULL,
                        `calllevel` char(1) DEFAULT NULL,
                        `agentfeetime` int(11) DEFAULT NULL,
                        `starttime` datetime DEFAULT NULL COMMENT '起始时间',
                        `stoptime` datetime DEFAULT NULL COMMENT '结束时间',
                        `pdd` int(11) DEFAULT NULL COMMENT '接通延迟(秒)',
                        `linepdd` int(11) DEFAULT NULL,
                        `waittime` int(11) DEFAULT NULL COMMENT '接续时长(秒)',
                        `holdtime` int(11) DEFAULT NULL COMMENT '通话时长(秒)',
                        `feeprefix` varchar(64) DEFAULT NULL COMMENT '计费前缀',
                        `feetime` int(11) DEFAULT NULL COMMENT '计费时长(秒)',
                        `fee` bigint(20) unsigned DEFAULT NULL COMMENT '通话费用(元)',
                        `package_id` int(11) DEFAULT NULL,
                        `package_fee` bigint(20) unsigned DEFAULT NULL COMMENT '套餐费用(元)',
                        `package_feetime` int(11) DEFAULT NULL COMMENT '套餐时长(秒)',
                        `account` varchar(32) DEFAULT NULL COMMENT '账户号码',
                        `account_name` varchar(255) DEFAULT NULL COMMENT '账户名称',
                        `enddirection` char(1) DEFAULT NULL COMMENT '挂断方',
                        `endreason` varchar(255) DEFAULT NULL COMMENT '终止原因',
                        `agentpackagefee` bigint(20) unsigned DEFAULT NULL,
                        `agentpackagefeetime` int(11) DEFAULT NULL,
                        `agentpackageid` int(11) DEFAULT NULL,
                        `agentaccount` varchar(255) DEFAULT NULL,
                        `agentname` varchar(255) DEFAULT NULL,
                        `agentfee` bigint(20) unsigned DEFAULT NULL COMMENT '落地费用(元)',
                        `agentfeeprefix` varchar(64) DEFAULT '0',
                        `gatewayrouting_type` int(11) DEFAULT NULL,
                        `caller_area` varchar(32) DEFAULT NULL COMMENT '主叫地区',
                        `area_code` varchar(32) DEFAULT NULL COMMENT '被叫地区',
                        `province` varchar(64) DEFAULT NULL,
                        `city` varchar(64) DEFAULT NULL,
                        `switch` varchar(64) DEFAULT NULL COMMENT '主叫经由VLS-switch',
                        `operators` int(11) unsigned DEFAULT '0',
                        `outgw_area` varchar(64) DEFAULT NULL,
                        `ingw_type` varchar(32) DEFAULT NULL,
                        `routetrace` varchar(320) DEFAULT NULL COMMENT '路由跟踪',
                        `call_encode` varchar(200) DEFAULT NULL COMMENT '语音编码',
                        `fee_type` char(1) DEFAULT NULL COMMENT '费率类型',
                        `fee_type_ee` char(1) DEFAULT NULL,
                        PRIMARY KEY (`id`),
                        KEY `index_account` (`account`),
                        KEY `index_account_name` (`account_name`),
                        KEY `index_agentaccount` (`agentaccount`),
                        KEY `index_caller` (`caller`),
                        KEY `index_callee` (`callee`),
                        KEY `index_callergatewayh323id` (`callergatewayh323id`(64)),
                        KEY `index_calleegatewayh323id` (`calleegatewayh323id`),
                        KEY `index_starttime` (`starttime`),
                        KEY `index_callerproductid` (`callerproductid`),
                        KEY `index_calleeproductid` (`calleeproductid`),
                        KEY `index_city` (`city`),
                        KEY `index_call_type` (`call_type`),
                        KEY `index_stoptime` (`stoptime`)
                )ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8");
            
        PREPARE createtablestmt FROM    @createTableStr;
        EXECUTE createtablestmt;
     
     
        -- 开启事务  注意: 必须要在建表语句下面  需要事务的地方进行 如果放在上面 则事务不起作用  
      START TRANSACTION ;
        
        
        -- 如果统计日期的话单详情表存在数据则先删除
        SET @delCDRTableStr = CONCAT( " DELETE FROM ", @tableName );
        PREPARE delCDRTableStmt FROM @delCDRTableStr;
        EXECUTE delCDRTableStmt;
        
        
        -- 同步抓取vlsdbcdr库统计日期的话单详情表数据  由于表数据量较大,采取分批插入 将EXECUTE结果赋值到@CDRTableRowCount变量中
        SET @countCDRTableStr = CONCAT( " SELECT COUNT(1) INTO @CDRTableRowCount FROM vlsdbcdr.", @tableName );
      PREPARE countCDRTableStmt FROM @countCDRTableStr;
        EXECUTE countCDRTableStmt;
        
        
      -- 计算需要插入的次数
        SELECT CEIL (@CDRTableRowCount / @EACH_INSERT_SIZE) INTO CDR_TABLE_INSERT_COUNT;
        
        WHILE @i <= CDR_TABLE_INSERT_COUNT DO
        
        
            SET @baseColumn = " `id`, `call_type`, `cb_sessionid`, `busiprefix`, `caller_brand`, `caller`, `calleraccess`, `callee_brand`, `callee`, `calleeaccess`, `calleeoriginal`,
                                                    `callerip`, `in_gw_media_ip`, `in_gw_media_isp`, `callergatewayh323id`, `callerproductid`, `callertogateway`, `calleeip`, `calleegatewayh323id`, `calleeproductid`,
                                                    `calleetogateway`, `rtp_ip`, `gd_gw_media_isp`, `billingmode`, `calllevel`, `agentfeetime`, `starttime`, `stoptime`, `pdd`, `linepdd`, `waittime`, `holdtime`,
                                                    `feeprefix`, `feetime`, `fee`, `package_id`, `package_fee`, `package_feetime`, `account`, `account_name`, `enddirection`, `endreason`, `agentpackagefee`,
                                                    `agentpackagefeetime`, `agentpackageid`, `agentaccount`, `agentname`, `agentfee`, `agentfeeprefix`, `gatewayrouting_type`, `caller_area`, `area_code`,
                                                    `province`, `city`, `switch`, `operators`, `outgw_area`, `ingw_type`, `routetrace`, `call_encode`, `fee_type`, `fee_type_ee` ";
                                                    
            SET @insertCDRStr = CONCAT(" INSERT INTO ", @tableName, "(", @baseColumn, ")", " SELECT ", @baseColumn, " FROM vlsdbcdr.", @tableName,
                                                                    " LIMIT ", (@i - 1) * @EACH_INSERT_SIZE, ",", @EACH_INSERT_SIZE );
     
            PREPARE insertCDRstmt FROM    @insertCDRStr;
            EXECUTE insertCDRstmt;
        
            SET @i = @i + 1;
            
        END WHILE;
        
        
        
        -- 删除销售客户账单表已存在的统计日期数据  
        DELETE FROM t_sale_customer_day_cost WHERE statistical_time = statistic_date;
        
        
        -- 向销售客户日账单表插入统计日期的数据  
        SET @insertSCDCStr = CONCAT( "
        
                INSERT INTO osp.t_sale_customer_day_cost
                    ( statistical_time, customer_id, account_id, service_type, fee_type, call_times, caller, caller_area, feetime, fee, create_time)
                SELECT '", statistic_date,"' AS statistical_time, (SELECT out_id FROM t_account AS A WHERE A.account_id = CDR.account AND A.type = 0) AS customer_id,
                        CDR.account, '5', CDR.fee_type, count(1) AS call_count, CDR.caller, CDR.caller_area, SUM(CDR.feetime / 60), SUM(CDR.fee), NOW()
                FROM ",
                    @tableName, " AS CDR
                WHERE
                    CDR.call_type = '5'
                GROUP BY
                    customer_id, CDR.account, CDR.call_type, CDR.fee_type ");
     
        PREPARE insertSCDCstmt FROM    @insertSCDCStr;
        EXECUTE insertSCDCstmt;
     
     
      -- 提交事务
        COMMIT ;
     
    END;
     
     
     
     
     
     
     

四 定时器代码

    package com.yzx.osp.modular.task.controlller;
     
    import com.yzx.osp.common.util.DateUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
     
    import java.util.Date;
     
    /**
     * @author yuanshushu
     * @date 2018/9/13
     * @description 话单详情定时任务类
     */
    @Component
    public class CdrDateTask {
     
        @Autowired
        private JdbcTemplate jdbcTemplate;
     
        @Scheduled(cron = "0/10 * *  * * ?")
        public void syncTCdrDateData() {
     
            try {
     
                // 按日期生成话单详情表
                this.jdbcTemplate.execute("call create_current_day_cdr_table()");
     
            } catch (Exception e) {
                e.printStackTrace();
            }
     
     
        }
     
     
    }

五. 存储过程DEMO     小
5.1 遍历分批插入

     
    CREATE PROCEDURE test () BEGIN
     
     
        DECLARE CDR_TABLE_ROW_COUNT BIGINT;
        DECLARE CDR_TABLE_INSERT_COUNT INT;
     
      -- 声明事务
        DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING ROLLBACK ;
        
        SET @EACH_INSERT_SIZE = 100;
        SET @i = 1;

        SELECT count(1) FROM t_cdr_20180811 INTO CDR_TABLE_ROW_COUNT;
        SELECT CEIL (CDR_TABLE_ROW_COUNT / @EACH_INSERT_SIZE) INTO CDR_TABLE_INSERT_COUNT;
     
        
        START TRANSACTION ;
        
     
        WHILE @i <= CDR_TABLE_INSERT_COUNT DO
            
     
            -- 拼接插入sql   注意: mysql  limit m,n  m为开始行数, n为查询行数  
            SET @insertStr = CONCAT( "
                            INSERT INTO t_cdr_20180812
                                    (call_type, cb_sessionid)
                            SELECT
                                    call_type, cb_sessionid
                            FROM
                                    t_cdr_20180811
                            limit ", (@i - 1) * @EACH_INSERT_SIZE, ",", @EACH_INSERT_SIZE );
                            
            PREPARE insertStrStmt FROM @insertStr;
            EXECUTE insertStrStmt;
                            
            SET @i = @i + 1;
            
        END WHILE;
        
        COMMIT ;
     
    END;
     

 5.2 获取EXECUTE执行结果
    -- statistic_date 统计日期  接收yyyy-MM-dd类型的时间字符串
    CREATE PROCEDURE create_current_day_cdr_table (IN statistic_date VARCHAR(64)) BEGIN   
        SET @tableName = 't_cdr_20180811';
        SET @countCDRTableStr = CONCAT( " SELECT COUNT(1) INTO @STABLE_CDR_ROW_COUNT FROM vlsdbcdr.", @tableName);
        PREPARE countCDRTableStmt FROM @countCDRTableStr;
        EXECUTE countCDRTableStmt;
        
        SELECT @STABLE_CDR_ROW_COUNT;
     
    END;
 

 

案例
建立数据集

#创建表
create table orders1 (
    orderid int(11) not null primary key ,
    Itemid varchar(30) not null ,
    category varchar(10) not null ,
    orderdate datetime not null ,
    sales float not null );#创建表
create table orders2 like orders1;
create table orders3 like orders1;
create table orders4 like orders1;
create table orders5 like orders1;
#插入数据
insert into orders1 (orderid, Itemid, category, orderdate, sales)
values ('1','k1','A','2020-1-2','459.5'),
       ('2','k2','A','2020-2-2','345.4'),
       ('3','k1','A','2020-1-7','47'),
       ('4','k3','C','2020-1-21','678'),
       ('5','k4','B','2020-5-2','345'),
       ('6','k5','C','2020-3-12','654'),
       ('7','k4','B','2020-4-25','464'),
       ('8','k2','A','2020-5-28','632'),
       ('9','k3','C','2020-7-20','98'),
       ('10','k5','C','2020-4-28','455.6'),
         ('11','k1','A','2020-3-27','459.7'),
       ('12','k2','A','2020-2-23','776.6'),
       ('13','k4','B','2020-2-12','759'),
       ('14','k5','C','2020-8-2','999'),
       ('15','k2','A','2020-9-21','599'),
       ('16','k3','C','2020-10-21','433'),
       ('17','k4','B','2020-10-28','232'),
       ('18','k5','C','2020-10-3','124'),
       ('19','k3','C','2020-6-6','321.4'),
       ('20','k4','B','2020-9-11','788.6');
 insert into orders2 (orderid, Itemid, category, orderdate, sales)
values ('21','k1','A','2020-1-3','954.5'),
       ('22','k2','A','2020-2-4','435.4'),
       ('23','k1','A','2020-1-8','74'),
       ('24','k3','C','2020-7-5','78'),
       ('25','k4','B','2020-5-26','35'),
       ('26','k5','C','2020-3-10','54'),
       ('27','k4','B','2020-4-29','44'),
       ('28','k2','A','2020-5-24','32'),
       ('29','k3','C','2020-7-7','98'),
       ('30','k5','C','2020-4-6','45.6'),
         ('31','k1','A','2020-3-23','49.7'),
       ('32','k2','A','2020-2-1','76.6'),
       ('33','k4','B','2020-2-18','759'),
       ('34','k5','C','2020-8-29','99'),
       ('35','k2','A','2020-9-29','59'),
       ('36','k3','C','2020-10-25','43'),
       ('37','k4','B','2020-10-28','22'),
       ('38','k5','C','2020-10-3','14'),
       ('39','k3','C','2020-6-10','31.4'),
       ('40','k4','B','2020-9-11','78.6');
insert into orders3 (orderid, Itemid, category, orderdate, sales)
values ('41','k1','A','2020-1-3','954.5'),
       ('42','k2','A','2020-2-4','435.4'),
       ('43','k1','A','2020-1-8','674'),
       ('44','k3','C','2020-7-5','478'),
       ('45','k4','B','2020-5-26','635'),
       ('46','k5','C','2020-3-10','654'),
       ('47','k4','B','2020-4-29','644'),
       ('48','k2','A','2020-5-24','632'),
       ('49','k3','C','2020-7-7','98'),
       ('50','k5','C','2020-4-6','645.6'),
         ('51','k1','A','2020-3-23','49.7'),
       ('52','k2','A','2020-2-1','676.6'),
       ('53','k4','B','2020-2-18','759'),
       ('54','k5','C','2020-8-29','99'),
       ('55','k2','A','2020-9-29','459'),
       ('56','k3','C','2020-10-25','443'),
       ('57','k4','B','2020-10-28','522'),
       ('58','k5','C','2020-10-3','614'),
       ('59','k3','C','2020-6-10','31.4'),
       ('60','k4','B','2020-9-11','78.6');
insert into orders4 (orderid, Itemid, category, orderdate, sales)
values ('61','k1','A','2020-1-3','954.5'),
       ('62','k2','A','2020-2-4','4435.4'),
       ('63','k1','A','2020-1-8','874'),
       ('64','k3','C','2020-7-5','778'),
       ('65','k4','B','2020-5-26','535'),
       ('66','k5','C','2020-3-10','754'),
       ('67','k4','B','2020-4-29','644'),
       ('68','k2','A','2020-5-24','932'),
       ('69','k3','C','2020-7-7','898'),
       ('70','k5','C','2020-4-6','645.6'),
         ('71','k1','A','2020-3-23','449.7'),
       ('72','k2','A','2020-2-1','376.6'),
       ('73','k4','B','2020-2-18','759'),
       ('74','k5','C','2020-8-29','399'),
       ('75','k2','A','2020-9-29','159'),
       ('76','k3','C','2020-10-25','343'),
       ('77','k4','B','2020-10-28','222'),
       ('78','k5','C','2020-10-3','114'),
       ('79','k3','C','2020-6-10','231.4'),
       ('80','k4','B','2020-9-11','178.6');
insert into orders5 (orderid, Itemid, category, orderdate, sales)
values ('81','k1','A','2020-1-3','1954.5'),
       ('82','k2','A','2020-2-4','1435.4'),
       ('83','k1','A','2020-1-8','174'),
       ('84','k3','C','2020-7-5','178'),
       ('85','k4','B','2020-5-26','35'),
       ('86','k5','C','2020-3-10','154'),
       ('87','k4','B','2020-4-29','144'),
       ('88','k2','A','2020-5-24','132'),
       ('89','k3','C','2020-7-7','198'),
       ('90','k5','C','2020-4-6','145.6'),
         ('91','k1','A','2020-3-23','149.7'),
       ('92','k2','A','2020-2-1','176.6'),
       ('93','k4','B','2020-2-18','1759'),
       ('94','k5','C','2020-8-29','199'),
       ('95','k2','A','2020-9-29','159'),
       ('96','k3','C','2020-10-25','143'),
       ('97','k4','B','2020-10-28','122'),
       ('98','k5','C','2020-10-3','114'),
       ('99','k3','C','2020-6-10','131.4'),
       ('100','k4','B','2020-9-11','178.6');

创建存储过程
创建一个表data来储存查询结果数据集

create table data (category varchar(10) not null ,orderid int(11) not null primary key ,
    Itemid varchar(30) not null ,
    sales float not null
);

#如果你需要调试存储过程一定要加这句代码
drop procedure if exists insert_odata;

存储过程主体

delimiter ;;
create procedure insert_odata (IN i int)
begin
    DECLARE i int;
    set i=1;
    while i<=5 do
          set @sqlStr:=CONCAT('insert into data (select category, orderid,Itemid,sales from(
select category,orderid,Itemid,sales,
           row_number()over(partition by category order by category,sales desc ) as ranking
    from orders',i,') t1 where ranking <=2);');
    prepare stmt from @sqlStr;
    execute stmt;
    deallocate prepare stmt;
          set i=i+1;
          end while
end
;;             
delimiter ;

调用存储过程,并查看数据结果

call insert_odata()
select * from data;

最后求所有数据每个category,sales的前两名

select category,orderid,Itemid,sales from
(select category,orderid,Itemid,sales,
       row_number()over(partition by category,Itemid order by category,sales desc ) as ranking
from data) t1 where ranking <=2
);

一点小拓展

我在第一次写的时候,因为不知道在MySQL中使用循环需要将其放入存储过程,我的思路是将表名作为变量创建存储过程,然后再通过循环调用存储过程,导致第一个方案用了两个存储过程。

create table data (category varchar(10) not null ,orderid int(11) not null primary key ,
    Itemid varchar(30) not null ,
    sales float not null
);
#第一个存储过程
#用表作为变量
drop procedure if exists insert_odata;
delimiter ;;
create procedure insert_odata (IN temp varchar(30))
begin
    set @tempStr:=CONCAT('insert into data (select category,orderid,Itemid,sales from(
select category,orderid,Itemid,sales,
           row_number()over(partition by category order by category,sales desc ) as ranking
    from ',temp,') t1 where ranking <=2);');
    prepare stmt from @tempStr;
    execute stmt;
    deallocate prepare stmt;
end
;;
delimiter ;

#第二个 存储过程
drop procedure if exists run;
delimiter $$
create procedure run()
    begin
        DECLARE i int;
        DECLARE Tname varchar(25);
        set i=1;
        while i<=5 do
            set Tname =concat('orders',i);
            call insert_odata(Tname);
            set i=i+1;
            end while;
    end
    $$

delimiter ;
call run();
select * from data;

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/142685.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式锁实现

分布式锁实现一 为什么要使用分布式锁二 分布式锁应该具备哪些条件三 分布式锁的三种实现方式四 基于数据库的实现方式五 基于Redis的实现方式一 为什么要使用分布式锁 我们在开发应用的时候&#xff0c;如果需要对某一个共享变量进行多线程同步访问的时候&#xff0c;可以使用…

HCIE-Security:顺利通过,备考心得

备考半年多&#xff0c;终于通过华为HCIE安全&#xff0c;今天把心得贴出来&#xff0c;供大家参考。 我是4月1日开始在机构开始学习安全IE的&#xff0c;报名之后从IA开始学习&#xff0c;学习期间也算勤勤恳恳&#xff0c;每次上课都进行预习和复习&#xff0c;形成自己的笔记…

论文投稿指南——中文核心期刊推荐(大气科学)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

2023-1-5 javaScript

JavaScript基础 javaScript 概念 概念&#xff1a;一门客户端脚本语言 脚本语言&#xff1a;不需要编译&#xff0c;直接就可以被浏览器解析执行了 功能&#xff1a;可以增强用户和heml页面交互的过程可以控制html元素&#xff0c;让页面有一些动态的效果&#xff0c;增强用…

[AHK]腾讯实时股票数据接口

腾讯财经接口获取最新行情以五粮液为例&#xff0c;要获取最新行情&#xff0c;访问数据接口&#xff1a;qt.gtimg.cn/qsz000858返回数据&#xff1a;v_sz000858"51~五 粮 液~000858~27.78~27.60~27.70~417909~190109~227800~27.78~492~27.77~332~27.76~202~27.75~334~27.…

[ERROR] Malformed \uxxxx encoding.报错解决

今天用idea运行完项目。想直接打包的时候&#xff0c;结果打包失败&#xff0c;一直报错 [ERROR] Malformed \uxxxx encoding. 网上查了之后&#xff0c;一直说是&#xff0c;有路径在使用斜杠的时候&#xff0c;使用错误。将"\“换成”/“就好了&#xff0c;但是我配置文…

pb将字符串中的中文和英文(含符号)拆分

//用于将字符串中的中文和英文(含符号)拆分 //uf_split_str_enorcn(as_inputstr) //as_inputstr:导入字符串 long i, li_len, li_lenA as_return_cn = as_return_en = if as_inputstr > then li_len = len(as_inputstr) //带中文长度 li_lenA = lenA…

ICMP隧道-调研笔记

ICMP隧道通信原理与通信特征 https://baijiahao.baidu.com/s?id1652047934643855432&wfrspider&forpc 1.一个正常的 ping每秒最多只会发送两个数据包&#xff0c;而使用ICMP隧道的浏览器在同一时间会产生大量ICMP 数据包 2.ICMP隧道数据包中DATA 往往大于64 比特 3.正…

TC275-11CCU6_PWM_Generation

基础知识 CCU6&#xff0c;Capture/Compare Unit 6捕获/比较单元&#xff0c;是一个专门用于电机控制而设计的16位捕获和比较单元。 CCU6包含多个定时器&#xff0c;将它们的计数值和参考值进行比较&#xff0c;来生成PWM信号。 定时器12&#xff08;T12&#xff09;配有三个…

Java并发编程(三)

临界区 临界资源&#xff1a;一次仅允许一个进程使用的资源成为临界资源 临界区&#xff1a;访问临界资源的代码块 竞态条件&#xff1a;多个线程在临界区内执行&#xff0c;由于代码的执行序列不同而导致结果无法预测&#xff0c;称之为发生了竞态条件 一个程序运行多个线…

日志框架之TLog讲解分析

文章目录1 TLog1.1 引言1.2 简介1.3 TLog操作1.3.1 pom.xml1.3.2 替换logback配置项1.3.3 测试1.4 TLog接入方式1.5 TLog的基本原理1.5.1 日志标签1.5.2 TLogContext1.5.3 TLogRPCHandler1.6 第三方框架的适配1.6.1 异步线程1.6.1.1 一般异步线程1.6.1.2 线程池1.6.2 对RPC框架…

应用程序性能瓶颈中的CPU缓存优化

1.前言 在应用程序中会有大量的对变量的操作&#xff0c;在一般情况下不会导致问题&#xff0c;但在多线程操作共享变量时&#xff0c;不当的操作会产生大量的冗余操作&#xff0c;造成性能的浪费。这篇文章主要从编码方式与逻辑策略对变量从CPU寄存器&#xff0c;CPU缓存&…

Redis面试题整理

认识Redis 什么是Redis? 一种基于内存的数据库&#xff1b;在内存中完成对数据的读写操作&#xff1b;读写速度非常快&#xff1b;常用于缓存&#xff0c;消息队列&#xff0c;分布式锁等场景 Redis和Memcached有什么区别&#xff1f; 共同点 都是基于内存的数据库&#x…

PaddleNLP系列课程二:RocketQA、SKEP(属性级情感分析)、通用信息抽取技术UIE

文章目录一、使用RocketQA搭建端到端的问答系统1.1 问答系统介绍1.2 RocketQA1.2.1 检索式QA VS预训练时代QA1.2.2 RocketQA简介1.3 使用RocketQA搭建问答系统1.3.1 安装1.3.2 使用预置模型完成预测1.3.3 搭建问答系统1.3.3.1 使用Faiss搭建自己的问答系统1.3.3.2 使用Jina搭建…

Leecode---141、142环形链表

141 难度 &#xff1a; easy 个人主要思路是&#xff0c; 循环遍历每个节点&#xff0c; 判断该节点此前是否被访问过。 方法一&#xff1a; 时间8ms &#xff0c; 内存 6.8M , func hasCycle(head *ListNode) bool {var val map[*ListNode]*ListNode{}if head nil {return …

l2逐笔接口数据传输延时高吗?

l2逐笔接口数据传输延时高吗&#xff1f;信息服务商的机器部署在交易所机房内&#xff0c;并通过接口直接向用户转发。按照交易所的规定&#xff0c;每个接收用户均需支付成本十几万&#xff0c;使用l2逐笔接口数据做量化是需要一定门槛。但用户端SDK直连的方式&#xff0c;能最…

C++学习 Day.9(宏和模板简介)

好久没更了&#xff0c;摆还是爽 遗留问题&#xff1a; (16条消息) int&作为函数返回类型-编程语言-CSDN问答&#xff08;已解决&#xff09; 宏&#xff1a; 预处理器编译指令都以#打头 #define&#xff08;宏常量&#xff09;使得预处理器进行文本替换&#xff0c;而不…

Acwing---795.前缀和

前缀和1.题目2.基本思想3.代码实现4.总结1.题目 输入一个长度为n的整数序列。 接下来再输入m个询问&#xff0c;每个询问输入一对l&#xff0c;r。 对于每个询问&#xff0c;输出原序列中从第l个数到第 r 个数的和。 输入格式 第一行包含两个整数n和m。 第二行包含n个整数&am…

一种简洁又不失优雅的工作流:极狐 flow

本文来自&#xff1a; 万金 极狐(GitLab)解决方案专家 杨周 极狐(GitLab) 高级解决方案架构师 极狐(GitLab) 市场部内容团队 我们提到的 Workflow 是指什么&#xff1f; 我们在日常开发工作中提到的 Workflow 通常是指通过 Git&#xff08;版本控制工具&#xff09;实现的分布式…