Подтвердить что ты не робот

Строка усекается по длине, но не разрезание слов разрешено

Я хочу ограничить длину поля строки в MYSQL на определенную длину, но я не хочу, чтобы какие-либо измельчения слов возникали.

Когда я это сделаю:

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

Я получаю это как вывод:

Business Analist met focus o

Но я хотел бы

Business Analist met focus

Как я могу ввести ограничение в 28 символов, но не прерывать слова? Конечно, легко [вставить язык программирования здесь];-), но я хочу знать, возможно ли это в MYSQL в простой инструкции.

4b9b3361

Ответ 1

Пусть @str будет вашей строкой и @len начальная позиция, на которую нужно нарезать. Затем необходимыми шагами могут быть:

  • Возьмите самые левые символы @len @str.

  • Отмените подстроку.

  • Найдите позицию первого пространства в обратной подстроке.

  • Вычитайте 1 из позиции. Но если пространство не найдено, пусть позиция остается 0.

  • Вычтите найденную позицию из @len и назовите ее cutpos.

  • Возьмите первые (самые левые) cutpos символы @str как 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

Ответ 2

Как насчет разбиения на пробелы:

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

вернет

Business Analist met focus

Ответ 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))

Ответ 4

В 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

EDIT: Я думаю, что для MYSQL замените "Locate" на "CharIndex"

Ответ 5

Настройте ответ на Нарни, здесь, который работает с двумя полями (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)
)

Мне нужно было что-то вроде этого, поэтому я добавил его. Может помочь кому-то другому.

Ответ 6

@Андрей Андреевич. Мне очень понравился ваш ответ:) Во всяком случае, я нахожусь на моем db, он работает лучше, если вы меняете строки 2 и 3 следующим образом:

SELECT
  IF(LENGTH(str)<[email protected],str,LEFT(str, cutpos)) AS str1,
  IF(LENGTH(str)<[email protected],'',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, то есть "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, или я просто неверно истолковал ваш код или что еще...

Ответ 7

Похоже, люди не читают руководство по 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) должен это сделать.