web-dev-qa-db-ja.com

文字列は長さで切り捨てられますが、単語を切り刻むことはできません

MYSQLの文字列フィールドの長さを特定の長さに制限したいのですが、単語の切り刻みが発生したくありません。

私がする時:

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

私はこれを出力として取得します:

Business Analist met focus o

でもお願いします

Business Analist met focus

28文字の制限を強制し、単語の切り刻みを防ぐにはどうすればよいですか?もちろん、[ここに選択したプログラミング言語を挿入]では簡単です;-)ですが、MYSQLで簡単なステートメントでそれが可能かどうかを知りたいです。

18
Ward Bekker

@strを文字列とし、@lenをカットする初期位置とします。次に、必要な手順は次のとおりです。

  1. @lenの左端の@str文字を取ります。

  2. 部分文字列を逆にします。

  3. 反転された部分文字列の最初のスペースの位置を見つけます。

  4. 位置から1を引きます。ただし、スペースが見つからない場合は、位置を0のままにします。

  5. 見つかった位置を@lenから減算し、それをcutposと呼びます。

  6. @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
10
Andriy M

スペースでの分割はどうですか?

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

戻ります

Business Analist met focus
11
JeffProd

非常に興味深い問題。これが私がそれをした方法です:

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

ナルニア国物語の答えに基づいて構築します。これは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)
)

私はこのようなものが必要だったので、それを追加しました。他の誰かを助けるかもしれません。

0
bicycle

シンプルな機能:

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

それが私のせいなのか、それとも何なのかはわかりませんが、逆に、長さが<@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の問題なのか、コードを誤って解釈しただけなのか、それとも他に何があるのか​​わかりません...

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」の代わりに「Locate」を使用すると思います

0
tkerwood