powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Дополнительная группировка данных в Pivot
8 сообщений из 8, страница 1 из 1
Дополнительная группировка данных в Pivot
    #39916901
heso
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день,
Просьба помочь, как из таблицы вида

id_param id_objectabcdefg11110NULLNULLNULLNULLNULLNULL12130NULLNULLNULLNULLNULLNULL32NULLNULL180NULLNULLNULLNULL42NULLNULLNULL150NULLNULLNULL
Получить выходную таблицу вида:
id_param id_objectabcdefg11110NULLNULLNULLNULLNULLNULL12130NULL180150NULLNULLNULL

Т.е сгруппировать данные по id_object

Создание:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
CREATE TABLE params
(
    id_param smallint PRIMARY KEY,
    name varchar(50) NOT NULL
)

CREATE TABLE objects_params
(
    id_object int,
    id_param smallint NOT NULL,
    cdate smalldatetime,
    value int
)

INSERT INTO dbo.params (id_param, name)
VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), 
       (5, 'e'), (6, 'f'), (7, 'g')

INSERT INTO dbo.objects_params (id_object, id_param, cdate, value)
VALUES (1, 1, '20191206',NULL), (1, 2,'20191212', 100), (1, 1, '20191201', 110),
       (2, 4, '20191211',120), (2, 1,'20190101', 130), (2, 3, '20191212', 140),
       (2, 4, '20191111',150), (2, 3,'20190201', 160), (2, 3, '20190312', 170),
       (2, 3, '20191201', 175),(2, 3, '20191202', 180), (2, 3, '20191203', 185),
       (2, 3, '20191204', 190)



Скрипт:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
DECLARE @userdate VARCHAR(MAX)
SET @userdate='20191202';

DECLARE @names as VARCHAR(MAX)
SELECT @names =
COALESCE(@names + ', ','') + QUOTENAME(name)
FROM
   (SELECT name
    FROM params 
   ) AS B;

DECLARE @SQL as VARCHAR(MAX)
SET @SQL = 
'WITH op as ( 
      SELECT op.id_object, op.id_param, name, op.cdate, op.value,
             ROW_NUMBER() OVER (PARTITION BY op.id_object, op.id_param ORDER BY op.cdate DESC) as seqnum
      FROM objects_params op JOIN
           params p
           ON op.id_param = p.id_param
		
      WHERE op.cdate <='''+ @userdate +'''
     )

SELECT id_param, id_object, ' + @names + '
FROM (
    select *
    from op
    where seqnum=1
    ) as tbl
pivot 
(
    max(value) for name in (' + @names + ')
) piv'

execute(@SQL)



P.s.
на SO помогли, но не до конца.

Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
Feb 10 2012 19:39:15
Copyright (c) Microsoft Corporation
Express Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: )
...
Рейтинг: 0 / 0
Дополнительная группировка данных в Pivot
    #39916904
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
heso
Просьба помочь, как из таблицы вида

id_param id_objectabcdefg11110NULLNULLNULLNULLNULLNULL12130NULLNULLNULLNULLNULLNULL32NULLNULL180NULLNULLNULLNULL42NULLNULLNULL150NULLNULLNULL

Получить выходную таблицу вида:
id_param id_objectabcdefg11110NULLNULLNULLNULLNULLNULL12130NULL180150NULLNULLNULL

Т.е сгруппировать данные по id_objectА в чём проблема? груп бай по полю id_object, и макс по остальным (возможно, мин по id_param, если не устраивает макс - вы не указали критерий).
...
Рейтинг: 0 / 0
Дополнительная группировка данных в Pivot
    #39916908
heso
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvg,

Когда я пытаюсь добавить group by id_object в данный блок:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT id_param, id_object, ' + @names + '
FROM (
    select *
    from op
    where seqnum=1
	group by id_object
    ) as tbl
pivot 
(
    max(value) for name in (' + @names + ')
	 
) piv'

execute(@SQL)



То выдает ошибку "Столбец "op.id_param" недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY."
...
Рейтинг: 0 / 0
Дополнительная группировка данных в Pivot
    #39916914
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
heso
Когда я пытаюсь добавить group by id_object в данный блок:
Нужно этот блок сделать подзапросом, а в верхнем запросе уже будет group by id_object
И не забыть сделать ещё одну переменную, как @names, только с описанием MAX(поле) as поле
...
Рейтинг: 0 / 0
Дополнительная группировка данных в Pivot
    #39916926
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
heso,

Примерно так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SET @SQL = 
'WITH op as ( 
      SELECT op.id_object, op.id_param, name, op.cdate, op.value,
             ROW_NUMBER() OVER (PARTITION BY op.id_object, op.id_param ORDER BY op.cdate DESC) as seqnum
      FROM objects_params op JOIN
           params p
           ON op.id_param = p.id_param
		
      WHERE op.cdate <='''+ @userdate +'''
     )--select * from op

SELECT id_param, id_object, ' + @names + '
FROM (
    select id_object, value, name, min(id_param) over (partition by id_object) as id_param
    from op
    where seqnum=1
    ) as tbl
pivot 
(
    max(value) for name in (' + @names + ')
) piv'


Можно будет уточнить, когда расскажите каким должен быть id_param в результате.
...
Рейтинг: 0 / 0
Дополнительная группировка данных в Pivot
    #39916942
heso
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,

Спасибо, работает.
В данном случае id_param Не имеет значения. В итоговой таблице его можно отбросить. (т.е SELECT id_param, id_object, ' + @names + ').
Пошел курить мануалы, чтобы понять, каким образом в данном примере работает MIN() OVER (PARTITION BY ()).

alexeyvg,
попробовал..может слишком в лоб:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
DECLARE @userdate VARCHAR(MAX)
SET @userdate='20191202';

DECLARE @names as VARCHAR(MAX)
SELECT @names =
COALESCE(@names + ', ','') + QUOTENAME(name)
FROM
   (SELECT name
    FROM params 
   ) AS B;

DECLARE @SQL as VARCHAR(MAX)
SET @SQL = 
'WITH op as ( 
      SELECT op.id_object, op.id_param, name, op.cdate, op.value,
             ROW_NUMBER() OVER (PARTITION BY op.id_object, op.id_param ORDER BY op.cdate DESC) as seqnum
      FROM objects_params op JOIN
           params p
           ON op.id_param = p.id_param
		
      WHERE op.cdate <='''+ @userdate +'''
     )
SELECT *
FROM (
	SELECT id_param, id_object, ' + @names + '
	FROM (
		select *
		from op
		where seqnum=1
		) as tbl
	pivot 
	(
		max(value) for name in (' + @names + ')
	) piv) try1
Group by id_object'

execute(@SQL)



Выскакивает аналогичная ошибка.
Не очень понял по поводу создания еще одной переменной. Для каких целей?
...
Рейтинг: 0 / 0
Дополнительная группировка данных в Pivot
    #39916945
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
heso
В итоговой таблице его можно отбросить
Тогда так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SET @SQL = 
'WITH op as ( 
      SELECT op.id_object, op.id_param, name, op.cdate, op.value,
             ROW_NUMBER() OVER (PARTITION BY op.id_object, op.id_param ORDER BY op.cdate DESC) as seqnum
      FROM objects_params op JOIN
           params p
           ON op.id_param = p.id_param
		
      WHERE op.cdate <='''+ @userdate +'''
     )
SELECT id_object, ' + @names + '
FROM (
    select id_object, value, name
    from op
    where seqnum=1
    ) as tbl
pivot 
(
    max(value) for name in (' + @names + ')
) piv'
...
Рейтинг: 0 / 0
Дополнительная группировка данных в Pivot
    #39916956
heso
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,

Блин. все гениальное просто. спасибо большое.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Дополнительная группировка данных в Pivot
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]