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

  • 相关阅读:
    mybaits错误解决:There is no getter for property named 'id' in class 'java.lang.String'(转)
    Tomcat配置虚拟路径
    FireFox背景亮度修改
    简单的百度贴吧爬虫实现(urllib)
    python知识总结
    QT-- MainWindow外的cpp文件调用ui
    数据结构--栈的实现
    数据结构-- 队列的实现
    经典排序算法---归并排序
    经典排序算法---希尔排序
  • 原文地址:https://www.cnblogs.com/psxfd4/p/12013451.html
Copyright © 2011-2022 走看看