Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Возможно ли упростить код?  [new]
ypmail
Member

Откуда:
Сообщений: 331
Здравствуйте.
При создании поля использую следующий код:
SELECT  (CASE WHEN Owner LIKE '[А-Я][А-Я]%' COLLATE Cyrillic_General_BIN OR Owner LIKE '%"%' THEN '' ELSE STUFF(REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(Owner)), ' ', CHAR(1) + ' '), ' ' + CHAR(1), ''), CHAR(1), ''),1,CHARINDEX(' ',REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(Owner)), ' ', CHAR(1) + ' '), ' ' + CHAR(1), ''), CHAR(1), ''),1),'') END) AS LastName FROM Table


Таблица с клиентами, которые записаны как Иванов Иван Иванович или ООО "Рога и копыта". Использую
CASE - для исключения организаций
LTRIM(RTRIM(Owner) - для удаления пробелов в начале и конце строки
REPLACE(REPLACE(REPLACE... - для удаления лишних пробелов внутри строки
STUFF - для обрезки фамилий

Код работает, но больно уж громоздкий получился, можно ли его как-то упростить, сделать компактнее?
29 янв 18, 16:33    [21147905]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33279
Блог
ypmail,

крайне странно, что у вас не различаются ФЛ и ЮЛ,
посмотрите ваши таблицы, может найдется признак
29 янв 18, 16:50    [21148011]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
ypmail
Member

Откуда:
Сообщений: 331
Критик
ypmail,

крайне странно, что у вас не различаются ФЛ и ЮЛ,
посмотрите ваши таблицы, может найдется признак

Такого признака точно нет, это данные из файла Excel, которые нужно импортировать в некую программу для дальнейшей подготовки писем клиентам. Поэтому "Уважаемый(ая) ООО "Рога и копыта" будут исключаться, останутся только Иваны Иванычи, по ЮЛ будет отдельная рассылка.
29 янв 18, 17:04    [21148069]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
ypmail,
Пришли тут, вывалили свое дендро-фекальное решение... Не код - а жуть какой-то - ни одного переноса строки!

Ну, поржали, и хватит.

подсказка есть CROSS APPLY ( SELECT [name] = ... ) и есть всякие CHARINDEX/PATHINDEX, REVERSE.
Можно и без последнего.

Что должен возвращать запрос на тестовых данных? Например таких?
WITH
t AS (
  SELECT
    [name] = 'Муаммар Мохаммед Абдель Салям Хамид Абу Меньяр аль-Каддафи'
  UNION ALL
  SELECT
    [name] = 'Бендер-Задунайский Остап Ибрагимович'
  UNION ALL
  SELECT
    [name] = 'Воробьянинов Ипполит "Киса" Матвеевич'
  UNION ALL
  SELECT
    [name] = 'ООО "Рога и Копыта"'
)
SELECT
  [LastName] = CASE 
    WHEN [name] LIKE '[А-Я][А-Я]%' COLLATE Cyrillic_General_BIN OR [name] LIKE '%"%' THEN '' 
    ELSE STUFF( REPLACE( REPLACE( REPLACE( LTRIM( RTRIM( [name] ) ), ' ', CHAR(1) + ' ' ), ' ' + CHAR(1), '' ), CHAR(1), '' ), 1, CHARINDEX( ' ',REPLACE( REPLACE( REPLACE( LTRIM( RTRIM( [name] ) ), ' ', CHAR(1) + ' ' ), ' ' + CHAR(1), '' ), CHAR(1), '' ),1 ),'' )
  END 
FROM
  t
29 янв 18, 17:14    [21148109]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
ypmail
Member

Откуда:
Сообщений: 331
Первые 2 записи выводит как надо
Третью тоже как надо, ибо не надо всяких кис в кавычках в имя вписывать, да и не встречал я в документах имён в кавычках.
Четрвёртую отфильтровало т.к. есть ОО и кавычки - это тоже нормально.
Даже если что-то лишнее окажется без значения, всё равно легче пробежаться по данным после импорта и поправить, чем вручную вносить все записи.

Всё работает как надо! Компактнее код сделать возможно?
29 янв 18, 17:39    [21148212]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
ypmail
Компактнее код сделать возможно?

Компактнее - нет. Нагляднее - да.
SELECT
  [LastName] = CASE 
    WHEN [name] LIKE '[А-Я][А-Я]%' COLLATE Cyrillic_General_BIN OR [name] LIKE '%"%' THEN '' 
    ELSE RIGHT( [clean_name], LEN( [clean_name] ) - CHARINDEX( ' ', [clean_name] ) )
  END 
FROM
  t
  CROSS APPLY (
    SELECT
      [clean_name] = REPLACE( REPLACE( REPLACE( LTRIM( RTRIM( [name] ) ), ' ', CHAR(1) + ' ' ), ' ' + CHAR(1), '' ), CHAR(1), '' )
  ) ss

Но... в целом решение так себе, если например, вдруг появится "XXI-век Технолоджис ПАО"
29 янв 18, 17:44    [21148227]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
ypmail
Member

Откуда:
Сообщений: 331
Руслан Дамирович
Но... в целом решение так себе, если например, вдруг появится "XXI-век Технолоджис ПАО"

Согласен, все LIKE не пропишешь, но лучше уж так чем вручную
    WHEN [name] LIKE '[А-Я][А-Я]%' COLLATE Cyrillic_General_BIN OR [name] LIKE '%[А-Я][А-Я]%' COLLATE Cyrillic_General_BIN OR [name] LIKE '%"%' THEN ''
29 янв 18, 17:54    [21148272]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
ypmail
Согласен, все LIKE не пропишешь, но лучше уж так чем вручную

Вообще-то я намекаю, что твоя задача - из разряда тыканья пальцем в небо.
Без всякого сарказма желаю удачи в нелегком деле ETL.
WITH
t AS (
  SELECT
    [name] = 'Муаммар Мохаммед Абдель Салям Хамид Абу Меньяр аль-Каддафи'
  UNION ALL
  SELECT
    [name] = 'Бендер-Задунайский Остап Ибрагимович'
  UNION ALL
  SELECT
    [name] = 'Воробьянинов Ипполит "Киса" Матвеевич'
  UNION ALL
  SELECT
    [name] = 'ООО "Рога и Копыта"'
  UNION ALL
  SELECT
    [name] = 'XXI-век Технолоджис ПАО'
  UNION ALL
  SELECT
    [name] = '109-й мотострелковый стройбат'
  UNION ALL
  SELECT
    [name] = 'Sith-Lord Vaider Darth'
)
SELECT
  [LastName] = CASE 
    WHEN ss.[possible_type] = 'Individual' THEN RIGHT( [clean_name], LEN( [clean_name] ) - CHARINDEX( ' ', [clean_name] ) )
    ELSE ''
  END,
  [Type] = ss.[possible_type]
FROM
  t
  CROSS APPLY (
    SELECT
      [clean_name] = REPLACE( REPLACE( REPLACE( LTRIM( RTRIM( [name] ) ), ' ', CHAR(1) + ' ' ), ' ' + CHAR(1), '' ), CHAR(1), '' ),
      [possible_type] = CASE
        WHEN [name] LIKE '%"%' THEN 'Legal'
        WHEN [name] LIKE '%[0-9]%' THEN 'Legal'
        WHEN [name] LIKE '%[IVXLCDM]%' AND [name] NOT LIKE '%[ABEFGHJKNOPQRSTUWYZ]%' THEN 'Legal'
        WHEN [name] LIKE '[А-Я][А-Я]%' COLLATE Cyrillic_General_BIN THEN 'Legal'
        ELSE 'Individual'
      END
  ) ss
29 янв 18, 18:47    [21148456]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
ypmail
Member

Откуда:
Сообщений: 331
Руслан Дамирович
Вообще-то я намекаю, что твоя задача - из разряда тыканья пальцем в небо.

Это я понимаю, вот только для этой задачи решение ещё никто не придумал, а очень хочется заменить ручной ввод хоть какой-то автоматизацией...
29 янв 18, 20:34    [21148751]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
ypmail
вот только для этой задачи решение ещё никто не придумал, а очень хочется заменить ручной ввод хоть какой-то автоматизацией...

Да тебе прямая дорога в создатели искусственного интеллекта.
Бросай это гиблое дело - автоматизировать не автоматизируемое.
Надо было ограничивать формат данных на этапе ввода, чтобы шаг влево, шаг вправо - расстрел. Ввод двух пробелов подряд - провокация.

Если твоя работа разовая, то "и так сойдет".

Если нет - твой вариант. Тогда слушай сюда:
Найди справочник ОПФ (организационно-правовых форм), сделай из него таблицу полных и сокращенных наименований.
Вот это из кода убери -
WHEN [name] LIKE '[А-Я][А-Я]%' COLLATE Cyrillic_General_BIN THEN 'Legal'

Добавь проверку
WHEN EXISTS( SELECT 1 FROM opf_table opf WHERE t.[name] LIKE '%' + opf.[short_name] + '%' OR t.[name] LIKE '%' + opf.[full_name] + '%' ) THEN 'Legal'

Вот тогда оно заиграет новыми красками лагов и тормозов.
30 янв 18, 10:46    [21149858]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли упростить код?  [new]
ypmail
Member

Откуда:
Сообщений: 331
Руслан Дамирович,
это будет требоваться может раз в полгода, а то и реже, а лагов и тормозов не надо
30 янв 18, 15:13    [21151448]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить