字符串截断长度,但不允许切断单词

时间:2011-07-11 13:13:31

标签: mysql sql substring

我想在一定长度上限制MYSQL中的字符串字段长度,但我不希望任何单词出现乱码。

当我这样做时:

SELECT SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 28)

我得到这个作为输出:

Business Analist met focus o

但我想

Business Analist met focus

如何强制限制28个字符,但要防止切断字词?当然,在[插入这里选择的编程语言]中很容易;-),但我想知道MYSQL中是否可以用一个简单的语句。

8 个答案:

答案 0 :(得分:11)

分割空格怎么样:

SELECT SUBSTRING_INDEX('Business Analist met focus op wet- en regelgeving',' ',4)

将返回

Business Analist met focus

答案 1 :(得分:10)

@str成为您的字符串,@len为您的初始位置。然后必要的步骤可能是:

  1. @len最左边的@str个字符。

  2. 反转子字符串。

  3. 找到反转子串中第一个空格的位置。

  4. 从职位中减去1。但如果找不到空格,请保持位置0

  5. @len中减去找到的排名并将其称为cutpos

  6. cutpos的第一个(最左侧)@str个字符设为str1,将所有其他字符(从cutpos+1开始)作为str2 }。

  7. SELECT
      LEFT(str, cutpos) AS str1,
      SUBSTRING(str, cutpos + 1) AS str2
    FROM (
      SELECT
        @str AS str,
        @len - IFNULL(NULLIF(LOCATE(' ', REVERSE(LEFT(@str, @len))), 0) - 1, 0) AS cutpos
    ) s
    

答案 2 :(得分:3)

非常有趣的问题。我是这样做的:

//gets initial string - use 29 instead of 28 to see if the 29th  character is a space
SELECT SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 29) 

//inverts the string, so we can get the first 
SELECT REVERSE( SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 29))

// find the charindex of the first space (last space in the string not reversed)
SELECT CHARINDEX(' ', REVERSE( SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 29)))

// get the substring from the first (last) space
SELECT  SUBSTRING(REVERSE( SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 29)), CHARINDEX(' ', REVERSE( SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 29))), 29)

// reverse the string again to unfold it.
SELECT REVERSE(SUBSTRING(REVERSE( SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 29)), CHARINDEX(' ', REVERSE( SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 29))), 29))


// to try different lengths...
DECLARE  @size  int
select @size = 24
SELECT REVERSE(SUBSTRING(REVERSE( SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, @size)), 
CHARINDEX(' ', REVERSE( SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, @size))), @size))

答案 3 :(得分:0)

在SQL中它将是......

select Substring('Business Analist met focus op wet- en regelgeving', 0 , 28 + 2 - CharIndex(' ',  REVERSE(SUBSTRING('Business Analist met focus op wet- en regelgeving', 0, 28 + 1 )),0))

我不知道MYSQL中是否有所有这些功能

编辑:我认为MYSQL替换“定位”为“CharIndex”

答案 4 :(得分:0)

以Narnian的答案为基础,这里有两个字段(a.product,a.descr)和字符串被截断时添加“...”的地方。 a.descr也可以是空的。

  IF (
CHARACTER_LENGTH(
  IF(
    a.descr = '',
    a.product,
    CONCAT_WS(' - ',a.product,a.descr)
  )
)>35,
IF(
  a.descr = '',
  CONCAT(
    REVERSE(SUBSTRING(REVERSE( SUBSTRING(a.product, 1, 35)), locate(' ', REVERSE( SUBSTRING(a.product, 1, 35))), 35)),
    '...'
  ),
  CONCAT(
    REVERSE(SUBSTRING(REVERSE( SUBSTRING(CONCAT_WS(' - ',a.product,a.descr), 1, 35)), locate(' ', REVERSE( SUBSTRING(CONCAT_WS(' - ',a.product,a.descr), 1, 35))), 35)),
    '...'
  )
),
CONCAT_WS(' - ',a.product,a.descr)
)

我需要这样的东西,这就是我添加它的原因。可能会帮助别人。

答案 5 :(得分:0)

@Andriy M.我非常喜欢你的答案:) 无论如何,如果你改变第2行和第3行,我会在我的数据库中找到它更好:

SELECT
  IF(LENGTH(str)<=@len,str,LEFT(str, cutpos)) AS str1,
  IF(LENGTH(str)<=@len,'',SUBSTRING(str, cutpos + 1)) AS str2
FROM (
  SELECT
    @str AS str,
    @len - IFNULL(NULLIF(LOCATE(' ', REVERSE(LEFT(@str, @len))), 0) - 1, 0) AS cutpos
  FROM @table
) s

不知道这是我的错还是什么,但另一方面,当它们的长度为&lt; @len时,有时会在第一个字母上截断字符串,即“First s” - “tring”而不是“First”字符串“当@ len = 13

我给你发了一个工作实例:

CREATE TABLE `test` (
  `sometext` varchar(65)
);

INSERT INTO `test` (`sometext`) VALUES
('Firs strin'),
('Alll right'),
('third string'),
('fourth string'),
('a longer example string'),
('Supercalifragilisticexpialidocious');

SELECT
  IF(LENGTH(str)<=12,str,LEFT(str, cutpos)) AS str1,
  IF(LENGTH(str)<=12,'',SUBSTRING(str, cutpos + 1)) AS str2
FROM (
  SELECT
    sometext AS str,
    12 - IFNULL(NULLIF(LOCATE(' ', REVERSE(LEFT(sometext, 12))), 0) - 1, 0) AS cutpos
  FROM test
) s

以下是使用原始代码的无效示例:

SELECT
  LEFT(str, cutpos) AS str1,
  SUBSTRING(str, cutpos + 1) AS str2
FROM (
  SELECT
    sometext AS str,
    12 - IFNULL(NULLIF(LOCATE(' ', REVERSE(LEFT(sometext,12))), 0) - 1, 0) AS cutpos
  FROM test
) s

我不确定这是一个utf8问题,还是我误解了你的代码,或者其他什么......

答案 6 :(得分:0)

简单功能:

DROP FUNCTION IF EXISTS fn_maxlen;
delimiter //
CREATE FUNCTION fn_maxlen(s TEXT, maxlen INT) RETURNS VARCHAR(255)
BEGIN

 RETURN LEFT(s, maxlen - LOCATE(' ', REVERSE(LEFT(s, maxlen))));

END//
delimiter ;

使用:

SELECT fn_maxlen('Business Analist met focus op wet- en regelgeving', 28);

答案 7 :(得分:-2)

似乎人们不会阅读mysql手册:

原文:SELECT SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 28)给出了破碎的词语。

修改:SELECT SUBSTRING_INDEX('Business Analist met focus op wet- en regelgeving', ' ' , 4)提供不间断的单词

SUBSTRING_INDEX(string, delimiter, number)将根据找到分隔符的次数截断字符串。 使分隔符成为空格,您将只获得整个单词。这样:

SUBSTRING_INDEX( LEFT('Business Analist met focus op wet- en regelgeving',28), ' ' , 4)应该这样做。