2017-06-12 51 views
-1

從一個字符串中提取的最大數目我有一個叫元素獲取用mysql

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/' 

回答

1

請檢查「LIKE」是如何工作的。 你可以使用百分比作爲百分比

只需更改您的查詢並添加%字符。它的工作

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

請注意:LIKE 'AES/JN/%'

0
SELECT MAX(Z.COUNT),reference FROM 
(
    SELECT reference,CAST(SUBSTRING_INDEX(reference, '/', -1) AS DECIMAL) count 
    FROM Elements where reference like 'AES/JN/%' 
)Z 

嘗試以上代碼。

希望這會有所幫助。

+0

做評論,如果你反對投票有一個人.. !! –

+0

我沒有降低這一個,但是誰曾經這麼做過,因爲你在使用子查詢時,如果沒有一個可以實現所需的結果。 – mickmackusa

+0

@mickmackusa是的。 –

0

請在下面找到解決方案。

查詢:

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 ; 

讓我知道,如果它不爲你工作

2

我幾乎希亞姆同意除外可​​怕錯綜複雜的功能。

我建議這個查詢:

SELECT SUBSTRING_INDEX(reference,'/',-1) as `max` 
FROM `Elements` 
WHERE reference LIKE 'AES/JN/%' 
ORDER BY reference DESC 
LIMIT 1 

這將輸出一個單行與2003作爲max列中的值。

我喜歡這種方法的原因是因爲CONVERT()被省略/不必要。

我把我的查詢與我的服務器上的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()已被基準測試,表現優於LIKE

補充閱讀:
MySQL LIKE vs 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; 
+1

您應該使用'LIKE'解決方案,並在'reference'列中添加一個索引。該索引將幫助'LIKE'執行得更快,並且它還會幫助'ORDER BY'。 LOCATE()解決方案不能使用索引,它會強制進行表掃描。使用EXPLAIN來確認。 –

+0

P.S. [不要使用MyISAM](https://stackoverflow.com/a/17706717/20860)。 :-) –