Php 获取使用mysql从字符串中提取的最大值

Php 获取使用mysql从字符串中提取的最大值,php,mysql,string,substring,Php,Mysql,String,Substring,我有一张叫做Elements的表 id reference 101 AES/JN/2001 102 AMES/JN/2001 103 AES/JN/2002 104 AES/JN/2003 105 AMES/JN/2002 我想从字符串中获取最大值。如果我的搜索关键字是AMES/JN,我应该得到2002。如果我的关键字是AES/JN,那么输出应该是2003 我尝试了以下代码: select max(convert(substring_index(reference,'

我有一张叫做Elements的表

id    reference
101   AES/JN/2001
102   AMES/JN/2001
103   AES/JN/2002
104   AES/JN/2003
105   AMES/JN/2002
我想从字符串中获取最大值。如果我的搜索关键字是AMES/JN,我应该得到2002。如果我的关键字是AES/JN,那么输出应该是2003

我尝试了以下代码:

select max(convert(substring_index(reference,'/', -1), unsigned)) as max
        FROM Elements  WHERE reference like 'AES/JN/'
试试上面的代码

希望这能有所帮助。

请检查“”的工作方式。 您可以使用%作为小丑

只需更改查询并添加%字符。这就是工作

    SELECT
    max(
        CONVERT (
            substring_index(reference, '/', - 1),
            UNSIGNED
        )
    ) AS max
FROM
    reference
WHERE
    reference LIKE 'AES/JN/%'

请注意:
如“AES/JN/%”
请找到以下解决方案

查询:

select id,reference,digits(reference) as num_values from asasas where reference like 'AMES/JN%' order by num_values DESC limit 1
您需要在mysql中创建一个函数

DELIMITER $$

DROP FUNCTION IF EXISTS `test`.`digits`$$

CREATE FUNCTION `digits`( str CHAR(32) ) RETURNS char(32) CHARSET latin1
BEGIN
  DECLARE i, len SMALLINT DEFAULT 1;
  DECLARE ret CHAR(32) DEFAULT '';
  DECLARE c CHAR(1);
  IF str IS NULL
  THEN 
    RETURN "";
  END IF;
  SET len = CHAR_LENGTH( str );
  REPEAT
    BEGIN
      SET c = MID( str, i, 1 );
      IF c BETWEEN '0' AND '9' THEN 
        SET ret=CONCAT(ret,c);
      END IF;
      SET i = i + 1;
    END;
  UNTIL i > len END REPEAT;
  RETURN ret;
END$$

DELIMITER ;

如果它对您不起作用,请告诉我

我几乎同意Shyam的观点,除了那可怕的复杂函数

我建议您这样做:

SELECT SUBSTRING_INDEX(reference,'/',-1) as `max`
FROM `Elements`
WHERE reference LIKE 'AES/JN/%'
ORDER BY reference DESC
LIMIT 1
这将输出一行,其中
2003
作为
max
列中的值

我喜欢这种方法的原因是
CONVERT()
被省略/不必要

我将我的查询与服务器上的Xenofexs'进行了比较,我的查询只比Xenofexs快了
.0001秒,但这只在OP发布的5行上运行。随着数据库容量的增加,我相信我的查询的性能领先优势会增加

即使您不关心微观优化,我认为这个查询更容易阅读/理解,因为它在函数中没有函数


事实上,我相信下一个查询可能比我上面的查询更好:

SELECT SUBSTRING_INDEX(reference,'/',-1) as `max`
FROM `Elements`
WHERE LOCATE('AES/JN/',reference)
ORDER BY reference DESC
LIMIT 1
由于
LOCATE()
将检查
reference
列中的前导字符,并且目标子字符串不会在字符串中出现,因此已对
LOCATE()
进行了基准测试,以使其性能优于

附加阅读:


下面是我使用的表格:

CREATE TABLE `Elements` (
  `id` int(10) NOT NULL,
  `reference` varchar(100) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `Elements` (`id`, `reference`) VALUES
(101, 'AES/JN/2001'),
(102, 'AMES/JN/2001'),
(103, 'AES/JN/2002'),
(104, 'AES/JN/2003'),
(105, 'AMES/JN/2002');

ALTER TABLE `Elements`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `Elements`
  MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=106;

如果你对某个人投了反对票,请发表评论。。!!我没有投反对票,但谁投过反对票,可能是因为你正在使用子查询,而不使用子查询就可以获得所需的结果。@mickmackusa是的。你应该使用
LIKE
解决方案,并在
reference
列上添加索引。该索引将帮助
LIKE
执行得更快,也将帮助
排序。LOCATE()解决方案无法使用索引,它将强制执行表扫描。请使用解释来确认此点。P.S.:-)
CREATE TABLE `Elements` (
  `id` int(10) NOT NULL,
  `reference` varchar(100) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `Elements` (`id`, `reference`) VALUES
(101, 'AES/JN/2001'),
(102, 'AMES/JN/2001'),
(103, 'AES/JN/2002'),
(104, 'AES/JN/2003'),
(105, 'AMES/JN/2002');

ALTER TABLE `Elements`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `Elements`
  MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=106;