Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 字符串长度截断,但不允许切碎单词_Mysql_Sql_Substring - Fatal编程技术网

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

Mysql 字符串长度截断,但不允许切碎单词,mysql,sql,substring,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个字符的限制,但防止切碎单词?当然,在[insert programming l

我想将MYSQL中的字符串字段长度限制在一定的长度上,但我不希望出现任何单词切碎的情况

当我这样做时:

SELECT SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 28)
我将此作为输出:

Business Analist met focus o
但是我想

Business Analist met focus
如何强制执行28个字符的限制,但防止切碎单词?当然,在[insert programming language of choice here];-)中很简单,但我想知道在MYSQL中是否可以用一个简单的语句来表示。

在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用“Locate”代替“CharIndex”是一个非常有趣的问题。我是这样做的:

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

@str
作为您的字符串,并将
@len
作为切割的初始位置。然后,必要的步骤可以是:

  • @str
    最左边的
    @len
    字符

  • 反转子字符串

  • 查找反向子字符串中第一个空格的位置

  • 从位置中减去
    1
    。但如果没有找到空间,则让位置保持
    0

  • @len
    中减去找到的位置,并将其称为
    cutpos

  • @str
    的第一个(最左边的)
    cutpos
    字符作为
    str1
    ,将所有其他字符(从
    cutpos+1开始)作为
    str2

  • 选择
    左(str,cutpos)为str1,
    子串(str,cutpos+1)作为str2
    从(
    挑选
    @str作为str,
    @len-IFNULL(NULLIF(定位(“”,反向(左(@str,@len))),0)-1,0)作为cutpos
    )
    
    基于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)
    )
    

    我需要这样的东西,所以我加了它。可能会帮助别人

    @Andrey 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
    

    我不确定这是否是utf8问题,或者我只是误解了您的代码,或者其他什么…

    在空格上拆分如何:

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

    Business Analist met focus
    

    似乎人们没有阅读mysql手册:

    原文:
    SELECT SUBSTRING('Business Analist met focus op wet-en regelgeving',1,28)
    给出了断字

    修改:
    SELECT SUBSTRING\u INDEX('Business Analist met focus op wet-en regelgeving','',4)
    给出完整的单词

    子字符串\u索引(字符串、分隔符、数字)
    将按找到分隔符的次数截断字符串。 将您的分隔符设为空格,您将只获得整个单词。因此:

    SUBSTRING\u索引(左('Business Analist met focus op wet-en regelgeving',28),'',4)
    应该这样做。

    简单功能:

    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 ;
    
    使用:


    您正在MySQL中寻找“word wrap”。有点。你需要逻辑。换句话说,您需要一个if语句。如果MySQL支持If,那么就使用它,否则,我认为这对MySQL来说是非常昂贵的操作。只要把这个词切掉,以后在你使用的任何编程语言中去掉它。@keymone不是真的,请参阅@bicycle的第5点(5.支持PHP而不是SQL)。在你的PHP中实现AVG和执行子字符串是有区别的。如果您正在执行子字符串,则可能需要在php中执行其他更复杂的操作。charindex不是有效的mysql函数。它应该被定位。顺便说一句,这应该是最好的答案。这对我来说很有效,但我不得不将CHARINDEX改为Locate。你有没有可能在大约3小时前否决了我的答案?如果是这样的话,如果你能详细说明你的理由,我将不胜感激。顺便说一句,当您在开始检查长度时,您正在验证
    descr
    是否为空,并根据这一点,单独检查
    产品
    的长度或用
    -
    分隔的两列的长度。但稍后,当您实际找到要切割的位置时,您不再检查
    descr
    是否为空。我认为,有时候这可能不会导致最精确的切割。确实如此,这一点很好。我只是调整了一下。是的,我否决了你,因为另一个答案更容易实现,没有太多的定制。但是应该进行调整,因为charindex不是一个有效的mysql方法,而quesion是关于mysql的。应改为locate。但它不包括在指定长度内找不到空格的情况。事实上,你的也一样。不过,我意识到,省略这个案例可能会让解决方案看起来更容易。不管怎样,谢谢你解释你的反对票!似乎有些人不假设通用输入。。。答案应该适用于任意数量的单词,而不仅仅是4个!子字符串的索引函数很有趣。
    SELECT SUBSTRING_INDEX('Business Analist met focus op wet- en regelgeving',' ',4)
    
    Business Analist met focus
    
    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);