Вопрос о функции SQL - PullRequest
       9

Вопрос о функции SQL

2 голосов
/ 24 апреля 2009

возникли проблемы с поиском параметров поиска для этой проблемы, поэтому я не могу найти ответ самостоятельно.

      <b>Column X</b>             |      
Message (info 1)           |
Message (info 2) (info 1)  |

Выше приведено содержимое одного столбца, который мне нужно обработать. Результатом запроса должна быть часть ВНУТРИ скобок. Проблема в том, что есть одна программа, которая сохраняет два набора информации в скобках, и в этом случае LATTER ( info 1 ) - это та, которую мы хотим в первом столбце, в дополнение к которому мы должны добавить второй столбец для информация 2 .

Итак, я представляю, что мне нужно объединить предложение if с переменной, от которой я могу зависеть, например, для подсчета количества оставшихся круглых скобок. Если left_parentheses = 2, то .... Иначе, если left_parentheses = 1, тогда ....

Но я не знаю, как это сделать в SQL, и я также не знаю, как разделить info 1/2 в примере.

Результат из примера будет выглядеть так:

<b>Column 1</b> | <b>Column 2</b>
 Info 1  |
 Info 1  |  Info 2

Как обычно, я постараюсь найти ответ, ожидая подсказок здесь. Спасибо!

Ответы [ 3 ]

4 голосов
/ 24 апреля 2009

Посмотрите на встроенные функции charindex, patindex и substring.

charindex находит положение указанного символа, patindex шаблона, substring возвращает часть строки по позиции.

Мой совет - написать представление над столбцом таблицы X, в котором используются указанные выше функции для предоставления двух вычисляемых столбцов. Тогда вы могли бы insert into result table select info1, info2 from columnX'stable;.

По крайней мере вычисляемый столбец info2 будет содержать оператор case для обработки случая, когда в источнике есть только одна «информация» в скобках, что-то вроде этого:

case when [some test using patindex too check for two parenthesized infos]
then [some combination of patidex and substring to extract the second info]
else null;

В частности, patindex возвращает ноль, когда шаблон не найден, так:

patindex('%(%)%(%)%', columnX)

вернет ноль для вашего первого примера, но не ваш второй пример.

Вам также нужно будет рассмотреть, как вы хотите обрабатывать ошибочные данные, в частности: 1) строки без круглых скобок, 2) с неравным числом открытых и закрывающих скобок, 3) с дополнительным текстом между двумя заключенными в скобки «данными», 4 ) с дополнительным текстом после закрывающей скобки.

Я бы рекомендовал вам добавить примеры всех этих возможностей, а также правильно отформатированные столбцы X к вашим тестовым данным, а затем проверить, что представление выполняет то, что вы хотите во всех случаях.

2 голосов
/ 24 апреля 2009

Потребуется много времени, если у вас есть приличный объем данных, но я сомневаюсь, что есть много лучших альтернатив, использующих SQL.

DECLARE @Table TABLE (TableID INT PRIMARY KEY, ColumnX VARCHAR(32))

INSERT INTO @Table VALUES (1, '(Info 1) (Info 2)');
INSERT INTO @Table VALUES (2, '(Info 1)');
INSERT INTO @Table VALUES (3, '(Info 10) (Info 20)');
INSERT INTO @Table VALUES (4, '(Info1')
INSERT INTO @Table VALUES (5, '(Info1) (Info2')
INSERT INTO @Table VALUES (6, '(Info1) Info2)')
INSERT INTO @Table VALUES (7, 'Info1')
INSERT INTO @Table VALUES (8, 'Info1)')
INSERT INTO @Table VALUES (9, NULL);

SELECT 
  TableID
  , [Column1] = CASE WHEN PATINDEX('%(%)%', ColumnX) = 1 
                THEN SUBSTRING(ColumnX
                               , CHARINDEX('(', ColumnX) + 1
                               , CHARINDEX(')', ColumnX) 
                                 - CHARINDEX('(', ColumnX) - 1
                             ) 
                ELSE NULL END
  , [Column2] = CASE WHEN PATINDEX('%(%)%(%)%', ColumnX) = 1 
                THEN SUBSTRING(ColumnX
                               , CHARINDEX('(', ColumnX, CHARINDEX('(', ColumnX) + 1) + 1
                               , CHARINDEX(')', ColumnX, CHARINDEX(')', ColumnX) + 1) 
                                 - CHARINDEX('(', ColumnX, CHARINDEX('(', ColumnX) + 1) - 1
                              )
                ELSE NULL END
FROM @Table
1 голос
/ 24 апреля 2009

Вот мой пример в синтаксисе SQL 2005 с использованием общего табличного выражения. Я не претендую на его правильность или эффективность, и я сделал некоторые предположения о том, как вы хотели, чтобы это работало.

WITH BracketIndeces AS
(
  SELECT 
    ColumnX AS ColVal,
    CHARINDEX('(', ColumnX) as first_open_bracket,
    CHARINDEX('(', ColumnX, CHARINDEX('(', ColumnX)+1) as second_open_bracket,
    CHARINDEX(')', ColumnX) as first_close_bracket,
    CHARINDEX(')', ColumnX, CHARINDEX(')', ColumnX)+1) as second_close_bracket
  FROM SomeTable
)
SELECT
  CASE
    WHEN second_close_bracket = 0 THEN
        SUBSTRING(ColVal, first_open_bracket+1, first_close_bracket - first_open_bracket-1)
    ELSE
        SUBSTRING(ColVal, second_open_bracket+1, second_close_bracket - second_open_bracket-1)      
  END AS Column1,
  CASE
    WHEN second_close_bracket = 0 THEN
        NULL
    ELSE
        SUBSTRING(ColVal, first_open_bracket+1, first_close_bracket - first_open_bracket-1)
  END AS Column2
FROM BracketIndeces
WHERE first_open_bracket <> 0
AND first_close_bracket <> 0
AND first_open_bracket < first_close_bracket
AND (
  (second_open_bracket = 0 AND second_close_bracket = 0) 
  OR
  (second_open_bracket < second_close_bracket 
    AND second_open_bracket > first_close_bracket
  )
)

Предложение where в нижней части просто отфильтровывает любые столбцы, которые либо не содержат скобок, либо содержат скобки в странном порядке, и использует NULL в Column2, когда присутствует только один набор скобок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...