MYSQLの文字列フィールドの長さを特定の長さに制限したいのですが、単語の切り刻みが発生したくありません。
私がする時:
SELECT SUBSTRING('Business Analist met focus op wet- en regelgeving', 1, 28)
私はこれを出力として取得します:
Business Analist met focus o
でもお願いします
Business Analist met focus
28文字の制限を強制し、単語の切り刻みを防ぐにはどうすればよいですか?もちろん、[ここに選択したプログラミング言語を挿入]では簡単です;-)ですが、MYSQLで簡単なステートメントでそれが可能かどうかを知りたいです。
@str
を文字列とし、@len
をカットする初期位置とします。次に、必要な手順は次のとおりです。
@len
の左端の@str
文字を取ります。
部分文字列を逆にします。
反転された部分文字列の最初のスペースの位置を見つけます。
位置から1
を引きます。ただし、スペースが見つからない場合は、位置を0
のままにします。
見つかった位置を@len
から減算し、それをcutpos
と呼びます。
@str
の最初の(左端の)cutpos
文字をstr1
とし、他のすべての文字(cutpos+1
から始まる)をstr2
とします。
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
スペースでの分割はどうですか?
SELECT SUBSTRING_INDEX('Business Analist met focus op wet- en regelgeving',' ',4)
戻ります
Business Analist met focus
非常に興味深い問題。これが私がそれをした方法です:
//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))
ナルニア国物語の答えに基づいて構築します。これは2つのフィールド(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)
)
私はこのようなものが必要だったので、それを追加しました。他の誰かを助けるかもしれません。
シンプルな機能:
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);
@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
それが私のせいなのか、それとも何なのかはわかりませんが、逆に、長さが<@lenの場合、最初の文字の文字列が切り捨てられることがありました。 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の問題なのか、コードを誤って解釈しただけなのか、それとも他に何があるのかわかりません...
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」の代わりに「Locate」を使用すると思います