Member 14684664 Ответов: 2

Как динамически преобразовать строку в столбец


Привет
У меня есть сценарий, в котором я должен использовать строку в качестве столбца, но динамически
 ID Bussiness 	   Date	         Value
1     	GPS	     Nov-18	         3
2     	GPS	     Dec-18	         2
3     	GPS	     Nov-18	         2
4     	GPS	     Dec-18	         3
and my aim is to have a out put like below;

ID	       Bussiness 	Nov-18	Dec-18
1 	        GPS	          3	    2
2	        GPS	          2	    3


ЯОД:
CREATE TABLE mytable(
   ID   INT   NOT NULL   
  ,Bussiness VARCHAR(3) NOT NULL
  ,Date VARCHAR(10) NOT NULL
  ,Value      INT  NOT NULL
  
);
INSERT INTO mytable( ID,Bussiness,Date, Value) VALUES
 (1,'GPS','Nov-18',3 )
,(2,'GPS','Dec-18',2 )
,(3,'GPS','Nov-18',2 )
,(4,'GPS','Dec-18',3 );

What I have tried:

<pre>go
;with cte as(
select row_number()over(partition by date order by ID)ID,
Bussiness,Date, Value 
from mytable
)
SELECT *
FROM cte
PIVOT (
	MAX([Value])
	FOR Date IN ( [Nov-18],[Dec-18])
) AS pvt

2 Ответов

Рейтинг:
16

MadMyche

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

Одно из правил, которое я использую, заключается в том, что если определенное имя столбца отображается в другом цвете, чем остальные в среде intellisense, его либо нужно изменить, либо правильно экранировать.
Обратите внимание, что даже в Редакторе CP, который не имеет всех определений SQL в нем, что "дата" имеет другой цвет. В моем локальном редакторе "значение" также меняет цвет

CREATE TABLE mytable(
   ID   INT   NOT NULL   
  ,Bussiness VARCHAR(3) NOT NULL
  ,Date VARCHAR(10) NOT NULL
  ,Value      INT  NOT NULL
  
);
Моя обычная процедура состояла бы в том, чтобы изменить имена оскорбительных столбцов; так что это то, что я сделал в этом тесте вашего кода, и все это сработало, и я получил желаемые результаты
DECLARE @mytable TABLE (
   ID   		INT   NOT NULL   
  ,Bussiness	VARCHAR(3) NOT NULL
  ,mDate		VARCHAR(10) NOT NULL
  ,mValue		INT  NOT NULL
  
);
INSERT @mytable( ID,Bussiness, mDate, mValue) VALUES
 (1,'GPS','Nov-18',3 )
,(2,'GPS','Dec-18',2 )
,(3,'GPS','Nov-18',2 )
,(4,'GPS','Dec-18',3 );

;with cte as(
	select row_number()over(partition by mDate order by ID) ID,
	Bussiness, mDate, mValue 
from @mytable
)

SELECT	*
FROM		cte
PIVOT (
	MAX([mValue])
	FOR mDate IN ( [Nov-18],[Dec-18])
) AS pvt
Если вы не можете изменить имена, то вам нужно обернуть оскорбительные столбцы в [квадратные скобки], и запуск этого кода также дает желаемые результаты
DECLARE @mytable TABLE (
   ID   		INT   NOT NULL   
  ,Bussiness	VARCHAR(3) NOT NULL
  ,[Date]		VARCHAR(10) NOT NULL
  ,[Value]		INT  NOT NULL
  
);
INSERT @mytable( ID,Bussiness, [Date], [Value]) VALUES
 (1,'GPS','Nov-18',3 )
,(2,'GPS','Dec-18',2 )
,(3,'GPS','Nov-18',2 )
,(4,'GPS','Dec-18',3 );

;with cte as(
	select row_number()over(partition by [Date] order by ID) ID,
	Bussiness, [Date], [Value] 
from @mytable
)

SELECT	*
FROM		cte
PIVOT (
	MAX([Value])
	FOR [Date] IN ( [Nov-18],[Dec-18])
) AS pvt

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


Maciej Los

5ed!

Member 14684664

Удалив комментарий он удалил ваш ваш ответ слишком печально,
Итак, мой вопрос состоял в том, что если у меня уже есть заполненная таблица, то как я могу запустить код ?

MadMyche

В моем примере использовалась таблица @Table, объявленная во время выполнения, чтобы я не сохранял данные на своем сервере; вы можете просто начать с CTE и отрегулируйте, чтобы соответствовать вашим именам таблиц/столбцов, как предписано

Member 14684664

Еще раз спасибо , я применил ваш совет к столбцам, и я получаю ниже ошибку, любую идею, что я делаю неправильно
Msg 488, Уровень 16, Состояние 1, Линия 51
Столбцы сводной группировки должны быть сопоставимы. Тип столбца "описание" - это "текст", который не сопоставим.

MadMyche

Типы данных TEXT и NTEXT не могут использоваться в сводных данных

Member 14684664

спасибо

Рейтинг:
1

Member 14684664

Thanks for the post ,
I have tried your steps first for the static to get the result before I move to the dynamic one but I get below error
"
Hide   Copy Code
Msg 488, Level 16, State 1, Line 51
Pivot grouping columns must be comparable. The type of column "description" is "text", which is not comparable.


"
any advice ?
thanks

Maciej Los

Извините, но я не могу читать в ваших мыслях или непосредственно с вашего экрана...