Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Динамический запрос, case  [new]
Earl11
Member

Откуда:
Сообщений: 66
Доброго времени суток. Имеется такой запрос.
SELECT [ITEMID],
MAX(CASE WHEN [atrib] = 'Клиент' THEN [VALUE] ELSE NULL END) AS ATTR1,
MAX(CASE WHEN [atrib] = 'Заказ' THEN [VALUE] ELSE NULL END) AS ATTR2,
...
...
...
MAX(CASE WHEN [atrib] = '....' THEN [VALUE] ELSE NULL END) AS ATTRN,
FROM table1 as f
GROUP BY [ITEMID] 


Как сделать его динамическим?

DECLARE @quer nvarchar(max),
		@atrid1 nvarchar(max) = '''Клиент''',
		@artid2 nvarchar(max) = '''Заказ''',

                 ---@artidN nvarchar(max) = '''...''',

		@num int = 1;



SET @quer = 'SELECT [ITEMID],
MAX(CASE WHEN [atrib] = '+@atridN+' THEN [VALUE] ELSE NULL END) AS ATTRN,'

print @quer
exec sp_executesql  @quer


Заранее благодарю.
16 окт 19, 00:57    [21995043]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36987
Тут, к сожалению, программист нужен, который умеет склеивать строки.
16 окт 19, 01:00    [21995044]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Earl11
Member

Откуда:
Сообщений: 66
Гавриленко Сергей Алексеевич,
Не получится "колхозности" в духе?
''+@atrid[case(@num as nvarchar)]+''

Через цикл
16 окт 19, 01:08    [21995048]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7771
Earl11,

динамический запрос - это "колхозность" в принципе и используется только в безвыходных ситуациях, а не "для удобства".
Вы можете использовать переменные и без динамического запроса.
16 окт 19, 11:55    [21995316]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Earl11
Member

Откуда:
Сообщений: 66
Владислав Колосов,
В таком случае, как решить задачу?
16 окт 19, 15:31    [21995638]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
invm
Member

Откуда: Москва
Сообщений: 9350
Earl11,

Как-то так
select
 'select [ITEMID], ' + 
 string_agg('max(case when [atrib] = ' + quotename(attr.v, '''') + ' then [VALUE] end as ATTR' + cast(attr.n as varchar(10)), ', ') within group (order by attr.n) +
 ' FROM table1 as f GROUP BY [ITEMID]'
from
 (values (1, 'Клиент'), (2, 'Заказ'), ..., (N, '...')) attr(n, v);

Если string_agg нету, то конкатенируйте через xml
16 окт 19, 15:51    [21995666]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7771
Earl11,

мне не совсем понятна идея использовать SQL сервер в качестве генератора запросов. Запросы можно формировать в клиентском приложении. И какая вообще преследуется цель.
16 окт 19, 16:09    [21995692]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Earl11
Member

Откуда:
Сообщений: 66
Владислав Колосов,
Смысл динамически создать таблицу т.к. количество атрибутов (atrib) велико и писать портянку для каждого MAX(CASE WHEN ....AS ATTR2 не очень хочется.
16 окт 19, 17:43    [21995784]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Earl11
Member

Откуда:
Сообщений: 66
invm,
Спасибо. А иного пути нет? string_agg не поддерживается, с xml не особо знаком.
16 окт 19, 17:46    [21995786]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Ftt330
Member

Откуда:
Сообщений: 7
Откройте курсор по списку атрибутов, вычитайте в цикле и сделайте склейку.
16 окт 19, 18:23    [21995803]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7771
Earl11,

понял, вы формируете динамический pivot.

https://stackoverflow.com/questions/10404348/sql-server-dynamic-pivot-query , например.
16 окт 19, 18:24    [21995804]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Earl11
Member

Откуда:
Сообщений: 66
Владислав Колосов,
Большое спасибо, помогло. Медленно, но верно)
17 окт 19, 01:08    [21995965]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Earl11
Member

Откуда:
Сообщений: 66
Ftt330,
Есть какой-нибудь пример, как это сделать?
17 окт 19, 10:24    [21996143]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Ftt330
Member

Откуда:
Сообщений: 7
Earl11,


DECLARE @atrib varchar(50), @stmt varchar(max);  
DECLARE atrib_crs CURSOR FOR  
SELECT 'Клиент' AS atrib
UNION
SELECT 'Заказ';

SET @STMT = 'SELECT ';

OPEN atrib_crs;  

FETCH NEXT FROM atrib_crs  
INTO @atrib;  

WHILE @@FETCH_STATUS = 0  
BEGIN  
   SET @stmt = @stmt + 'CASE WHEN ATRIB = ''' + @atrib + ''' THEN VALUE END, ';
   FETCH NEXT FROM atrib_crs  
   INTO @atrib;
END  

CLOSE atrib_crs;  
DEALLOCATE atrib_crs;  

SET @stmt = SUBSTRING(@stmt, 1, LEN(@stmt) - 1) + ' FROM TABLE';

print @stmt;
GO  
17 окт 19, 12:05    [21996360]     Ответить | Цитировать Сообщить модератору
 Re: Динамический запрос, case  [new]
Earl11
Member

Откуда:
Сообщений: 66
Ftt330,
Большое спасибо
17 окт 19, 18:44    [21996865]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить