Задать вопрос
@NIKA_R

Как правильно обрабатывать концевые пробелы в SQL Server и PostgreSQL?

Есть задача учебного характер.
Для таблицы Outcomes преобразовать названия кораблей, содержащих более одного пробела, следующим образом.
Заменить все символы между первым и последним пробелами (исключая сами эти пробелы) на символы звездочки (*)
в количестве, равном числу замененных символов.
Вывод: название корабля, преобразованное название корабля.

Содержимое таблицы со сгенерированными тестовыми данными.
69134f35ada6f362425607.png

Мой запрос.
SELECT
    ship AS original_ship_name,
    CASE
        WHEN total_spaces >= 2 THEN
            first_part +
            ' ' + REPLICATE('*', middle_length) + ' ' +
            last_part
        ELSE NULL
    END AS transformed_ship_name
FROM (
    SELECT
        ship,
        CHARINDEX(' ', ship) AS first_space_pos,
        DATALENGTH(ship) - CHARINDEX(' ', REVERSE(ship)) + 1 AS last_space_pos,
        DATALENGTH(ship) - DATALENGTH(REPLACE(ship, ' ', '')) AS total_spaces
    FROM Outcomes
) AS precalc
CROSS APPLY (
    SELECT
        -- Всё до первого пробела (если есть)
        CASE WHEN first_space_pos > 0
             THEN SUBSTRING(ship, 1, first_space_pos - 1)
             ELSE ''
        END AS first_part,
        -- Всё после последнего пробела (если есть)
        CASE WHEN last_space_pos <= DATALENGTH(ship)
             THEN SUBSTRING(ship, last_space_pos + 1, DATALENGTH(ship) - last_space_pos)
             ELSE ''
        END AS last_part,
        -- Число звёздочек: минимум 1, даже если между пробелами пусто
        CASE
            WHEN last_space_pos > first_space_pos
            THEN CASE
                 WHEN (last_space_pos - first_space_pos - 1) > 0
                 THEN last_space_pos - first_space_pos - 1
                 ELSE 1  -- если между пробелами 0 символов → 1 звёздочка
            END
            ELSE 1  -- если первый и последний пробел совпадают → 1 звёздочка
        END AS middle_length
) AS parts
WHERE total_spaces >= 2


Результат на тестовой площадке
69134f801ff03924927017.png

Нейросети задачу не тянут. На каких данных запрос возвращает неверный результат. Что это за нерассмотренный мной крайний случай? (LEN не используется по причине некорректной обработки краевых пробелов)
  • Вопрос задан
  • 38 просмотров
Подписаться 1 Средний Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Инженер по тестированию
    5 месяцев
    Далее
  • Нетология
    Инженер по тестированию
    8 месяцев
    Далее
  • Skillbox
    Java-разработчик
    8 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Что-то вы перемудрили.
WITH
  cte AS (
    SELECT name,
           SPLIT_PART(name, ' ', 1) first,
           SPLIT_PART(name, ' ', -1) last
    FROM outcomes
  ),
  cte2 AS (
    SELECT name, first, last,
           LENGTH(name) - LENGTH(first) - LENGTH(last) - 2 middlelen
    FROM cte
  )
SELECT name,
       first || ' ' || REPEAT('*', middlelen) || ' ' || last starname
FROM cte2
WHERE middlelen > 0
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы