2

私は patindex と charindex を使用してみましたが、どちらも私が望むことを簡単に実行できないようです。charindex は一度に 1 つのシンボルのみを検索したいのですが、patindex は「検索元」のインデックスを許可していないため、循環してシンボルのすべてのインデックスを見つけることができません。私のオプションは何ですか?

4

1 に答える 1

2

あなたの「特別なシンボル」が何であるか、どのように保存されているか、どのような出力が期待されているかについての具体的な詳細はありませんが、少し推測作業が必要ですが、私の答えの基本的な原則は関係なく適用できると思います. すべてのオカレンスを取得するための鍵は、再帰 CTE を とともに使用することOUTER APPLYです。CTE がループするたびに、特殊文字がなくなるまで特殊文字をスペースに置き換え、文字の位置を保存します。

サンプルデータ:

DECLARE @SpecialSymbols TABLE (Symbol CHAR(1) NOT NULL PRIMARY KEY)
INSERT @SpecialSymbols VALUES ('@'), ('.'), ('['), (']')

DECLARE @TestData TABLE (StringToTest VARCHAR(100))
INSERT @TestData VALUES 
    ('test 1 [Using Square Brackets]'), 
    ('[Test2@EmailAddress.com]'), 
    ('No Special Symbols')

実際のクエリ

;WITH CTE AS
(   SELECT  *, STUFF(StringToTest, Position, 1, ' ') [ReworkedString]
    FROM    @TestData
            OUTER APPLY
            (   SELECT  CHARINDEX(Symbol, StringToTest) [Position], Symbol
                FROM    @SpecialSymbols
            ) Symbols
    WHERE   Position > 0
    UNION ALL
    SELECT  StringToTest, Symbols.Position, Symbols.Symbol, STUFF(ReworkedString, Symbols.Position, 1, ' ') [ReworkedString]
    FROM    CTE
            OUTER APPLY
            (   SELECT  CHARINDEX(Symbol, ReworkedString) [Position], Symbol
                FROM    @SpecialSymbols
                WHERE   Symbol = CTE.Symbol
            ) Symbols
    WHERE   Symbols.Position > 0
)

-- CTE NOW LOOKS LIKE:
--  | test 1 [[Using Square Brackets]   |   8   |   [   | test 1  [Using Square Brackets]
--  | test 1 [[Using Square Brackets]   |   30  |   ]   | test 1 [[Using Square Brackets 
--  | [Test2@EmailAddress.com]          |   20  |   .   | [Test2@EmailAddress com]
--  | [Test2@EmailAddress.com]          |   7   |   @   | [Test2 EmailAddress.com]
--  | [Test2@EmailAddress.com]          |   1   |   [   |  Test2@EmailAddress.com]
--  | [Test2@EmailAddress.com]          |   24  |   ]   | [Test2@EmailAddress.com 
--  | test 1 [[Using Square Brackets]   |   9   |   [   | test 1   Using Square Brackets]

SELECT  a.StringToTest, COALESCE(Location, '') [SpecialSymbolLocations]
FROM    @TestData a
        LEFT JOIN
        (   SELECT  DISTINCT
                    StringToTest,
                    -- THIS MERELY CONCATENATES ROWS INTO COLUMNS TO GET COMMA SEPARATED LIST
                    STUFF(( SELECT  ', ' + CONVERT(VARCHAR, Position)
                            FROM    CTE b
                            WHERE   a.StringToTest = b.StringToTest
                            ORDER BY Position
                            FOR XML PATH('')
                    ), 1, 2, '') [Location] 
            FROM    CTE a
        ) b
            ON a.StringToTest = b.StringToTest

CTE は好きなように操作できますが、完全を期すために、SQL サーバーの XML 拡張機能を使用して特殊記号の場所をカンマ区切りのリストに連結し、これらを元の各記号の隣に配置する最終クエリを追加しました。文字列。したがって、最終的な出力は次のようになります。

| StringToTest                      | SpecialSymbolLocations    |
|-----------------------------------|---------------------------|
| test 1 [[Using Square Brackets]   | 8, 9, 31                  |
| [Test2@EmailAddress.com]          | 1, 7, 20, 24              |
| No Special Symbols                |                           |
于 2012-04-18T10:21:23.347 に答える