Как создать объединенную строку значений строк на основе флагов в SQL Server - PullRequest
0 голосов
/ 20 марта 2012

Я использую SQL Server 2008r2.

Вот что я пытаюсь сделать:

У меня есть таблица с дизайном:

Flag  Text
________________________
0     'No Error'
1     'Bad Data'
2     'Bad Header'
4     'Unknown error'

Мой второй стол предназначен:

ID   Flags
_______________________
500  0
501  3
502  4
504  6
550  0

Флаги во второй таблице представляют побитовую комбинацию флагов в первой таблице (например, Flags = 3 - «Плохие данные» И «Плохой заголовок», Flags = 6 - «Плохой заголовок» И «Неизвестная ошибка») .

Я хочу запрос, который выдаст следующее:

ID   ConcatText
____________________________
500  'No Error'
501  'Bad Data, Bad Header'
502  'Unknown error'
504  'Bad Header, Unknown error'
550  'No Error'

Каков наилучший способ добиться этого без использования пользовательских функций или пользовательских хранимых процедур?

Спасибо за любую помощь.

Ответы [ 3 ]

2 голосов
/ 20 марта 2012

Эта статья объясняет, как именно это сделать.Он складывает это шаг за шагом, чтобы вы тоже поняли, что происходит.Он в основном объединяет побитовые операторы в SQL, а затем все остальное выполняется аналогично тому, что опубликовал hkf.Надеюсь, это полезно для вас:)

Я считаю, что это будет:

SELECT a.id,
    REPLACE(REPLACE(REPLACE(
    ( 
        SELECT TEXT
        FROM FlagTable AS b 
        WHERE a.flags & b.flag <> 0 
        ORDER BY b.text FOR XML Raw
    )
    , '"/><row value="', ', '), '<row value="', ''), '"/>', '') 
    AS 'attributes'
FROM FlagMappingTable AS a
ORDER BY a.id;
0 голосов
/ 20 марта 2012

О, я люблю побито, правда, не сарказм.Я думаю, что это самое простое.У вас есть CTE, я говорю, используйте их!Попробуй это.Я заимствовал из Объединить много строк в одну текстовую строку? с моим собственным видом соединения для побитового.* Я прошу прощения за ошибки, это не проверено и написано в блокноте.

WITH lines AS
( 
    SELECT
        row_number() over(order by ID) lineid,
        FlagMap.ID
        , Flag.Text AS ConcatText
    FROM
        FlagMap
    LEFT JOIN
        Flags
            ON FlagMap.Flags & Flags.Flag = Flags.Flag
                OR (FlagMap.Flags = 0 AND Flag.Flag = 0)
), 
result_lines AS
(
    SELECT
        lineid,
        cast(ConcatText as nvarchar(max)) ConcatText
    FROM
        lines
    WHERE
        lineid = 1

    UNION ALL

    SELECT
        l.lineid, 
        cast(r.ConcatText + N', ' + l.ConcatText AS nvarchar(max))
    FROM
      lines l 
    INNER JOIN
        result_lines r 
            on 
                l.lineid = r.lineid + 1 
) 
SELECT
    ID
    , ConcatText
FROM
    result_lines
ORDER BY
    ID DESC
0 голосов
/ 20 марта 2012

Вам нужна комбинация CROSS APPLY и FOR_XML_PATH()

См. Моделирование функции MySQL group_concat в Microsoft SQL Server 2005?

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