Mysql 字符串长度截断,但不允许切碎单词
我想将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
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);