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

  • 相关阅读:
    C#中Dictionary的用法
    System.Timers.Timer用法
    C#中的异步调用及异步设计模式(三)——基于事件的异步模式
    C#中的异步调用及异步设计模式(二)——基于 IAsyncResult 的异步设计模式
    C#中的异步调用及异步设计模式(一)
    [你必须知道的异步编程]——异步编程模型(APM)
    strncasecmp与strcasecmp用法
    C语言之strrchr函数
    HDU 5289 Assignment (ST算法区间最值+二分)
    poj 1733 Parity game(种类并查集)
  • 原文地址:https://www.cnblogs.com/psxfd4/p/12013451.html
Copyright © 2011-2022 走看看