0x01AA Ответов: 2

Как я могу показать подробные строки в виде столбцов (бесплатные настраиваемые пользовательские свойства) с помощью MS SQL


Уважаемые эксперты, пожалуйста, просветите меня.

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

Предположим, что у нас есть главный стол ...
CREATE TABLE Products
(
  Id   int,
  Name char(50)
);
INSERT INTO Products(Id, Name) VALUES (1, 'Prod1'),(2, 'Prod2');

... и таблица, содержащая определенные пользователем свойства и значения
CREATE TABLE ProductUserProperties
(
  Id            int,
  MasterId      int,
  PropertyName  char(50),
  PropertyValue char(50)
);
INSERT INTO ProductUserProperties (Id, MasterId, PropertyName, PropertyValue) VALUES
(1, 1, 'PropA', 'Prod1PropA_UserValue'),
(2, 1, 'PropB', 'Prod1PropB_UserValue'),
(3, 2, 'PropA', 'Prod2PropA_UserValue'),
(4, 2, 'PropB', 'Prod2PropB_UserValue');

Простой запрос по левым соединениям ...
SELECT 
  Products.Id                          Products_Id,
  Products.Name                        Products_Name,
  ProductUserProperties.Id  	       ProductUserProperties_Id,
  ProductUserProperties.MasterId       ProductUserProperties_MasterId,
  ProductUserProperties.PropertyName   ProductUserProperties_PropertyName,
  ProductUserProperties.PropertyValue  ProductUserProperties_PropertyValue
FROM Products
LEFT JOIN ProductUserProperties ON ProductUserProperties.MasterId = Products.Id
ORDER BY Products.Id, ProductUserProperties.PropertyName

...результаты в (сокращенные имена столбцов):

Prod_Id Prod_Name  ProdUsrProps_Id  ProdUsProp_MstrId  PropertyName  PropertyValue
1       Prod1      1                1                  PropA         Prod1PropA_UserValue                            
1       Prod1      2                1                  PropB         Prod1PropB_UserValue
2       Prod2      3                2                  PropA         Prod2PropA_UserValue
2       Prod2      4                2                  PropB         Prod2PropB_UserValue


Но мне нравится иметь что-то вроде этого
Products_Id  Products_Name PropA                    PropB                        Prop#
1            Prod1         Prod1PropA_UserValue     Prod1PropB_UserValue         ...
2            Prod2         Prod2PropA_UserValue     Prod2PropB_UserValue         ....


Наконец-то вопрос
Я знаю, как получить желаемый результат с помощью динамически создаваемых SQL-файлов.
Но мой вопрос таков: могу ли я получить желаемый результат только с "чистым" SQL, используя CTE, PIVOT и т. д., исключая хранимые процедуры?

Заранее Вам большое спасибо ;)

Что я уже пробовал:

Читал о CTE, Pivot и много гуглил. Но на данный момент я все еще не имею ни малейшего представления :(

Afzaal Ahmad Zeeshan

Я не знаю, как вы сравниваете pivot с хранимой процедурой? Хранимая процедура-это просто функция, где стержень-это то, что вы ищете здесь.

Я думаю, что поворот вокруг PropertyName это то, что вы хотите... Потому что нет никакого способа вернуть столбцы на основе таких свойств, как ... [PropertyValue] as 'PropA' так как данные переплетены.

Читайте дальше Поворот здесь и посмотрите, может быть, этот образец вам что-то скажет.

0x01AA

"Я не знаю, как вы сравниваете pivot с хранимой процедурой? - А я нет! Как вы пришли к этому странному утверждению?

Мой единственный вопрос: Могу ли я сделать это с помощью "только sql" или это возможно только с помощью динамически создаваемых операторов sql?

- Прочтите подробнее о PIVOT здесь и посмотрите, говорит ли вам что-нибудь этот образец.":
Я много читал и не нашел никакого решения. Вот почему мой вопрос здесь....

Afzaal Ahmad Zeeshan

Как это динамически создаваемые операторы SQL нет язык SQL?

0x01AA

Серьезно?
Конечно, в конце концов динамически создаваемый sql-элемент-это sql.

Как я уже сказал в вопросе: "я знаю, как получить желаемый результат с помощью динамически создаваемых SQL-файлов."

Но мой вопрос заключается в том, Могу ли я сделать это со стандартным sql без "внешней" помощи.


2 Ответов

Рейтинг:
1

Richard Deeming

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

Что-то вроде этого должно сработать:

DECLARE @columns nvarchar(max) = N'';
DECLARE @columns2 nvarchar(max) = N'';

SELECT 
    @columns += N', ' + QUOTENAME(RTRIM(PropertyName)), 
    @columns2 += N', u.' + QUOTENAME(RTRIM(PropertyName))
FROM 
    (SELECT DISTINCT PropertyName FROM ProductUserProperties) As p
ORDER BY 
    PropertyName
;


DECLARE @sql nvarchar(max) = N'WITH ctePivot As
(
    SELECT MasterId' + @columns + N'
    FROM (SELECT MasterId, PropertyName, PropertyValue FROM ProductUserProperties) As u
    PIVOT ( Max(PropertyValue) FOR PropertyName In (' + STUFF(@columns, 1, 2, N'') + N')) As p
)
SELECT
    p.Id, p.Name' + @columns2 + N'
FROM
    Products As p
    LEFT JOIN ctePivot As u
    ON u.MasterId = p.Id
ORDER BY
    p.Id
;';

EXEC sp_executesql @sql;
Сгенерированный динамический запрос будет выглядеть примерно так:
WITH ctePivot As
(
    SELECT MasterId, [PropA], [PropB]
    FROM (SELECT MasterId, PropertyName, PropertyValue FROM ProductUserProperties) As u
    PIVOT ( Max(PropertyValue) FOR PropertyName In ([PropA], [PropB])) As p
)
SELECT
    p.Id, p.Name, u.[PropA], u.[PropB]
FROM
    Products As p
    LEFT JOIN ctePivot As u
    ON u.MasterId = p.Id
ORDER BY
    p.Id
;


Рейтинг:
1

RickZeeland

Я думаю, что это случай для ДЕЛО, смотрите пример здесь: sql server - как транспонировать строки в столбцы в SQL? - администраторы баз данных Stack Exchange[^]


0x01AA

Нет, извините... Я не люблю расширять SQL в случае, если будет добавлено другое свойство. Заслуживает 1 но поскольку вы пытаетесь помочь это заканчивается нейтральным 3

[Редактировать]
И пожалуйста, удалите свой бесполезный ответ, что вопрос остается без ответа и, надеюсь, будет дан ответ некоторыми профессионалами! Вы даже не читали подробностей, кажется, вы просто гуглили по каким-то ключевым словам. А пока я вижу, как ты охотишься на рэпа....

RickZeeland

Это неправда, я попытался найти пример, который очень похож на ваш запрос, и это потребовало некоторых усилий. Вы правы, что случай-это уродливая конструкция, но лучше уродливое решение, чем никакого решения :)

0x01AA

Я был довольно груб, извините за это.