определить конкретное c число из сообщения, содержащего несколько цифр - PullRequest
0 голосов
/ 19 июня 2020

У меня есть требование выбрать 3-е число c значения из сообщения. Это число может иметь длину 1, 2, 4 и т. Д. c. Я использую PATINDEX для получения индекса числа, но не знаю, как заставить его искать 3-е число напрямую.

Сообщение:

'Successfully imported 6609 records and updated 0 records for a total of 6609 records into the table'

Запрос:

select (PATINDEX('%[0-9]%', 'Successfully imported 6609 records and updated 0 records for a total of 6609 records into the table')

Измененный запрос:

SELECT SUBSTRING
('Successfully imported 6609 records and updated 0 records for a total of 6609 records into the table .%' ,
PATINDEX('%total of%' ,'Successfully imported 6609 records and updated 0 records for a total of 6609 records into the table .%') + 9, 
5)

Я получаю результат как 6609, который указан c только для этого сообщения, но если мое сообщение: «Успешно импортировано 6 записей и обновлено 0 записей, всего 6 записей в таблице». , то я не получаю ожидаемого результата.

Ожидаемый результат:

6609 -- 3rd numeral

Ответы [ 5 ]

1 голос
/ 19 июня 2020

Возможно, не лучшее решение, но оно работает:

WITH source(message) AS
  (SELECT 'Successfully imported 1 records and updated 2 records for a total of 3 records into the table')
SELECT value
FROM SOURCE CROSS apply
  (SELECT row_number() OVER (ORDER BY message) POSITION, value
   FROM string_split(message, ' ')
   WHERE try_cast(value AS int) IS NOT NULL) AS a
WHERE POSITION = 3
0 голосов
/ 19 июня 2020

Если ваше третье число является последним числом в вашей строке (всегда), вы можете использовать это ниже logi c, чтобы получить третье число -

Демо здесь

DECLARE @T VARCHAR(1000)
SET @T = 'Successfully imported 6609 records and updated 0 records for a total of 6609 records into the table'


SELECT 
REVERSE
(
    SUBSTRING
    (
        REVERSE(@T),
        PATINDEX('%[0-9]%', REVERSE(@T)),
        (CHARINDEX(' ',REVERSE(@T),PATINDEX('%[0-9]%', REVERSE(@T))))-(PATINDEX('%[0-9]%', REVERSE(@T)))
    )
)
0 голосов
/ 19 июня 2020

Basi c в ваших 2 примерах, вам нужно значение после total of, поэтому просто найдите его, а затем первый пробел после:

SELECT TRY_CONVERT(int,SUBSTRING(V.YourString,PI.I+DATALENGTH('total of '),CHARINDEX(' ',V.YourString,PI.I+DATALENGTH('total of ')) - (PI.I+DATALENGTH('total of '))))
FROM (VALUES('Successfully imported 6609 records and updated 0 records for a total of 6609 records into the table'),
            ('Successfully imported 6 records and updated 0 records for a total of 6 records into the table .'))V(YourString)
     CROSS APPLY (VALUES(PATINDEX('%total of%',V.YourString)))PI(I)
0 голосов
/ 19 июня 2020

Я пробовал запрос ниже, и он работает должным образом.

SELECT SUBSTRING
('Successfully imported 0 records and updated 0 records for a total of 0 records into the table .%' ,
PATINDEX('%total of%' ,'Successfully imported 0 records and updated 0 records for a total of 0 records into the table .%') + 9, 
PATINDEX('%records into the table%' ,'Successfully imported 0 records and updated 0 records for a total of 0 records into the table .%') -
(PATINDEX('%total of%' ,'Successfully imported 0 records and updated 0 records for a total of 0 records into the table .%') + 9) )
0 голосов
/ 19 июня 2020

Базы данных вообще не подходящее место для манипуляций со строками, такого рода работа должна выполняться во внешнем интерфейсе. Однако вы можете использовать следующие

SELECT TOP 1 WITH TIES T.String, SS.Value
FROM
(
  VALUES
  ('Successfully imported 6609 records and updated 0 records for a total of 6609 records into the table'),
  ('Successfully imported 6609 records and updated 0 records for a total of 9999 records into the table')
) T(String)
CROSS APPLY
(
  SELECT ROW_NUMBER() OVER(ORDER BY TRY_CAST(Value AS INT)) RN,
         Value
  FROM STRING_SPLIT(String, ' ')
) SS
ORDER BY RN DESC;

Online Demo

...