zoukankan      html  css  js  c++  java
  • mysql函数使用的例子

    有以下图片的一个sql需求

     我不是很理解,这样的操作为什么要用数据库语句来实现。但我还是试一试吧

    ts_job里的每一条数据的dev_id都要计算它的包含几个shorter列中的字母。我实在想不出来怎样的语句可以一次查询出来。如果使用函数的话,应该可以。

    函数的要求是提供一个字符串,返回它包含几个shorter列的字母。这里要设置变量来存储这个值,由于我没怎么了解sql函数,只好按自己的想法写。

    先建两个表td_dev_type和ts_job

    DROP TABLE IF EXISTS `td_dev_type`;
    CREATE TABLE `td_dev_type`  (
      `TYPE_ID` smallint(6) NOT NULL AUTO_INCREMENT,
      `SHORTER` char(1) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
      PRIMARY KEY (`TYPE_ID`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;
    
    -- ----------------------------
    -- Records of td_dev_type
    -- ----------------------------
    INSERT INTO `td_dev_type` VALUES (1, 'F');
    INSERT INTO `td_dev_type` VALUES (2, 'D');
    INSERT INTO `td_dev_type` VALUES (3, 'B');
    INSERT INTO `td_dev_type` VALUES (4, 'C');
    INSERT INTO `td_dev_type` VALUES (5, 'C');
    DROP TABLE IF EXISTS `ts_job`;
    CREATE TABLE `ts_job`  (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `DEV_ID` varchar(64) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
      PRIMARY KEY (`ID`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;
    
    -- ----------------------------
    -- Records of ts_job
    -- ----------------------------
    INSERT INTO `ts_job` VALUES (1, 'G004B001');
    INSERT INTO `ts_job` VALUES (2, 'G001F002B34Ds');
    INSERT INTO `ts_job` VALUES (3, 'G001C001B001C');
    INSERT INTO `ts_job` VALUES (4, 'G004BCCB222D');

    现在考虑函数,我必须遍历一遍td_dev_type来获取一列shorter,每次都要与参数做是否包含的判断,判断成功就是计数变量加1

    drop function if exists countShorters;
    create function countShorters(dev_id varchar(64)) returns int #这里根据dev_id的类型设置
    begin
    set @num:=0;
    return (select @num:=IF(instr(dev_id,shorter)>0,@num+1,@num) nums from (select distinct shorter from td_dev_type) a order by nums desc limit 1); -- distinct 控制重复的字符是否也算
    end;

    其中核心

    set @num:=0;
    select @num:=IF(instr('G001B001CFC',shorter)>0,@num+1,@num) num from (select distinct shorter from td_dev_type) a

    这样在查询的过程中根据条件设置用户变量num的值,得出的num列的数值的最后一行是最终结果,我使用倒序排列再limit 1 的方法得到这个值 。使用distinct则字符串依次与F/D/B/C判断,这样结果不会重复,不加的话重复的字符会多判断;注意这与字符串中字符的重复无关。

    使用函数要注意:return行和end行末尾要加分号,不然会报错。而且我遇到的一个难题是无法使用局部变量,使用局部变量后结果是错的,不得已使用了用户变量。

    现在进行测试

    select countShorters('FDBCccC464B615')   # 结果为4 
    select countShorters('G004232001001910B0001')   # 结果为1

    最终语句

    select countShorters(dev_id) from ts_job tj

    此时可以满足需求。

    还有个问题,我不清楚sql函数的生命周期和作用范围,这个函数是在什么环境下创建一次还是每次执行语句时运行该函数(如果已存在其不会重新创建),这样的需求用数据库做是不合适的,仅仅把这个作为一个练手。

  • 相关阅读:
    spark 读取mongodb失败,报executor time out 和GC overhead limit exceeded 异常
    在zepplin 使用spark sql 查询mongodb的数据
    Unable to query from Mongodb from Zeppelin using spark
    spark 与zepplin 版本兼容
    kafka 新旧消费者的区别
    kafka 新生产者发送消息流程
    spark ui acl 不生效的问题分析
    python中if __name__ == '__main__': 的解析
    深入C++的new
    NSSplitView
  • 原文地址:https://www.cnblogs.com/psxfd4/p/12013451.html
Copyright © 2011-2022 走看看