Как мне повернуть это в T-SQL? - PullRequest
0 голосов
/ 28 мая 2010

Как мне получить это:

entityid    name                 stringvalue
----------- -------------------- --------------------
1           ShortDescription     Coal
1           LongDescription      BlackCoal
1           ShortDescription     Gold
1           LongDescription      WhiteGold
1           ShortDescription     Steel
1           LongDescription      StainlessSteel

Чтобы стать этим:

entityid    ShortDescription     LongDescription
----------- -------------------- --------------------
1           Coal                 BlackCoal
1           Gold                 WhiteGold
1           Steel                StainlessSteel

Код, который у меня пока есть:

    select *
from (select entityid, cast(name as nvarchar(20)) as name, cast(stringvalue as nvarchar(20)) as stringvalue from metapropertyvalue) as d
pivot
(
    max(stringvalue)
    for [name] in ([ShortDescription],[LongDescription])
)
as p

Большое спасибо всем,

Мт.

Ответы [ 3 ]

0 голосов
/ 28 мая 2010

Ключевое слово pivot предназначено исключительно для агрегации. Скорее всего, вам придется делать это вручную через подзапросы.

Кроме того, ваше расположение таблицы - действительно плохая идея. Я делал это раньше, я знаю много других людей, которые делали это раньше, это хорошо масштабируется НЕ . Самая большая проблема в том, что вы не можете правильно определить индексы в ваших данных. Вы должны серьезно рассмотреть вопрос об изменении таблицы непосредственно на ваш "сводный" формат, так как в любом случае это правильный реляционный стиль.

0 голосов
/ 28 мая 2010

Предполагая, что ваш DBRM не может быть изменен, это самое близкое, что я могу получить после нескольких обходных путей:

select TOP 1 Id
    , LEFT(ShortDescription, LEN(ShortDescription) - 1) as ShortDescription
    , LEFT(LongDescription, LEN(LongDescription) - 1) as LongDescription
from (
    select Entity_Id as Id
            , (
                select StringValue + N', ' as [text()]
                    from MyEntities
                    where [Name] LIKE N'ShortDescription'
                    FOR XML PATH(N'')
            ) as ShortDescription
            , (
                select StringValue + N', ' as [text()]
                    from MyEntities
                    where [Name] LIKE N'LongDescription'
                    FOR XML PATH(N'')
            ) as LongDescription
        from MyEntities
) e

Что приведет к выводу:

Id | Краткое описание | LongDescription

1 | Уголь, Золото, Сталь | BlackCoal, WhiteGold, нержавеющая сталь

И я сомневаюсь, что это работает, хотя я не знаю вашей ситуации.

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

Кстати, материал PIVOT и такая агрегация будут работать только тогда, когда данные состоят из чисел. Были бы другие способы достичь желаемого результата, если бы ваши столбцы [Name] и StringValue были бы числовыми.

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

Вместо того, чтобы проектировать таблицу, как вы, и всегда нужно «сводить» ее и делать какой-то сложный код для извлечения информации из нее, в дополнение к тому, что в столбце [Имя] всегда указывается, является ли это ShortDescription или LongDescription Я бы порекомендовал следующее, чтобы спроектировать таблицу так, как вам нужны данные для вывода, так как это нормально, если можно так выразиться.

IF OBJECT_ID(N'MyEntitiesTable') IS NOT NULL
    DROP TABLE MyEntitiesTable
GO

CREATE TABLE MyEntitiesTable (
    EntityId int IDENTITY(1, 1) NOT NULL PRIMARY KEY
    ShortDescription nvarchar(10) NOT NULL
    LongDescription nvarchar(50) NOT NULL
)
GO

insert into MyEntities (ShortDescription, LongDescription) values (N'Coal', N'BlackCoal')
GO
insert into MyEntities (ShortDescription, LongDescription) values (N'Gold', N'WhiteGold')
GO
insert into MyEntities (ShortDescription, LongDescription) values (N'Steel', N'WhiteSteel')
GO

Таким образом, все, что вам нужно будет написать как запрос, это:

select EntityId
        , ShortDescription
        , LongDescription
    from MyEntitiesTable

Что касается поля EntityId, то если вы абсолютно хотите, чтобы оно всегда было числом 1, то вы можете пропустить IDENTITIY(1, 1) PRIMARY KEY при создании таблицы. Однако я настоятельно рекомендую вам оставить его там, так как это определяет ваш первичный ключ, и ни одна таблица в вашей модели не должна иметь первичного ключа.

Причина этого предпочтительного подхода заключается в том, что для каждого описания, которое вы должны добавить в таблицу данных, вам придется выполнить два оператора INSERT. Это излишне убивает транзакции с вашей базой данных, а также делает ее очень трудной для использования, как вы можете видеть в текущей ситуации.

0 голосов
/ 28 мая 2010

Оставляя в стороне расположение таблицы, чтобы делать то, что вы хотите, не следует использовать PIVOT, для этого вам понадобятся подзапросы.

...