Teradata convert varchar column row values to Columns - sql

I have the following data:
create volatile table current_data(
id integer
, rownumber integer
, text_value varchar(10)
) on commit preserve rows;
insert into current_data values(1,1,'Text 1');
insert into current_data values(1,2,'Text 2');
insert into current_data values(1,3,'Text 3');
insert into current_data values(2,1,'Text 1');
insert into current_data values(2,2,'Text 2');
How can I convert the current_data to my desired_data as such?
create volatile table desired_data(
id integer
, text_value1 varchar(10)
, text_value2 varchar(10)
, text_value3 varchar(10)
)
on commit preserve rows;
insert into desired_data values(1,'Text 1','Text 2','Text 3');
insert into desired_data values(2,'Text 1','Text 2',null);
*** Note, I would have included pictured results however I don't have proper access.

You can use conditional aggregation:
select id,
max(case when rownumber = 1 then text_value end) as text_value1,
max(case when rownumber = 2 then text_value end) as text_value2,
max(case when rownumber = 3 then text_value end) as text_value3
from current_data
group by id;

You're asking for the Pivot -Function of Teradata.

Related

How make a pivot table using different column as reference?

I don't know how to get this result (see image) if I have this information:
CREATE TABLE TABLE_1
(
FECHA DATE NOT NULL
,LUGAR VARCHAR2(5) NOT NULL
,TIPO_USO VARCHAR2(2) NOT NULL
,NUM_PERSONAS NUMBER
,FORM_PAGO VARCHAR2(255) NOT NULL
);
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/01','RR/MM/DD'),'H1','U1','3','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/01','RR/MM/DD'),'H1','U3','2','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/01','RR/MM/DD'),'H1','U4','4','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H3','U2','1','ticket');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H4','U5','2','ticket');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H5','U1','3','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H5','U3','2','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/02','RR/MM/DD'),'H5','U4','4','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/03','RR/MM/DD'),'H10','U1','3','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/03','RR/MM/DD'),'H10','U2','1','tarjeta');
Insert into TABLE_1 (FECHA,LUGAR,TIPO_USO,NUM_PERSONAS,FORM_PAGO) values (to_date('19/04/03','RR/MM/DD'),'H12','U3','2','ticket');
CREATE SEQUENCE "SEQ_REPORTE" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 2206 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ;
CREATE TABLE TABLE_2 (
ID NUMBER DEFAULT SEQ_REPORTE.nextval NOT NULL
,FECHA DATE NOT NULL
,LUGAR VARCHAR2(5) NOT NULL
,U1 NUMBER
,U2 NUMBER
,U3 NUMBER
,U4 NUMBER
,U5 NUMBER
,FORM_PAGO VARCHAR2(255) NOT NULL
);
i want to get this : (see image)
Can somebody help me?
Thanks so much
Regards
You can try using conditional aggregation
select FECHA,LUGAR,
max(case when TIPO_USO='U1' then NUM_PERSONAS end) as U1,
max(case when TIPO_USO='U2' then NUM_PERSONAS end) as U2,
max(case when TIPO_USO='U3' then NUM_PERSONAS end) as U3,
max(case when TIPO_USO='U4' then NUM_PERSONAS end) as U4,
max(case when TIPO_USO='U5' then NUM_PERSONAS end) as U5,FORM_PAGO
from tablename
group by FECHA,LUGAR,FORM_PAGO

Table transformation logic in SQL

I have a table T :
CREATE TABLE T
(
id INT,
type VARCHAR(200),
type_value VARCHAR(10),
value VARCHAR(200)
);
INSERT INTO T VALUES (1, 'RoomColor', 'room1', 'yellow');
INSERT INTO T VALUES (1, 'RoomColor', 'room2', 'red');
INSERT INTO T VALUES (2, 'RoomColor', 'room1', 'blue');
INSERT INTO T VALUES (2, 'RoomColor', 'room1', 'pink');
INSERT INTO T VALUES (3, 'RoomColor', 'room1', 'white');
INSERT INTO T VALUES (3, 'RoomColor', 'room2', 'grey');
INSERT INTO T VALUES (3, 'RoomColor', 'room2', 'brown');
INSERT INTO T VALUES (4, 'RoomColor', 'room3', 'green');
I need to transform it into :
id BedRoomColor DiningRoomColor
-------------------------------------------
1 yellow red
2 blue pink
3 white grey
4 green null
Logic behind the transformation:
If there are more than two room type_value then discard the third room type_value
For same id if there are more than one room type_value ( for example room1,room1 or room2,room2 or room1,room2) then use first type_value to create as BedRoomColor and second type_value to create DiningRoomColor
If there is only 1 room type_value (for eg. room1 or room2 or room3) for an id then corresponding value ( red,green,yellow etc ) will be placed in BedRoomColor and DiningRoomColor will be null
I am struggling with this logic for couple of days. Can anyone please help me.
Thanks
You can use this script
;WITH CTE AS (
SELECT *, RN = ROW_NUMBER() OVER(PARTITION BY id ORDER BY type_value) FROM T
)
SELECT id, [1] BedRoomColor, [2] DiningRoomColor FROM
(SELECT id,value, RN FROM CTE ) SRC
PIVOT (MAX(value) FOR RN IN ([1], [2]) ) AS PVT
Result:
id BedRoomColor DiningRoomColor
----------- ------------------ ---------------
1 yellow red
2 blue pink
3 white grey
4 green NULL
Another way and with adding type to query is:
;with tt as (
select *,
row_number() over (partition by [type], id order by type_value) rn
-- ^^^^^^ I add type to support other types if there is
from t
)
select id,
max(case when [type] = 'RoomColor' and rn = 1 then [value] end) 'BedRoomColor',
max(case when [type] = 'RoomColor' and rn = 2 then [value] end) 'DiningRoomColor'
from tt
group by id;
SQL Server Fiddle Demo
try this:
with tmp as (
select T.*, rownumber() over(patition by id order by type_value) rang
from T
)
select f1.id, f1.value as BedRoomColor, f2.value as DiningRoomColor
from tmp f1
left outer join tmp f2 on f1.id=f2.id and f2.rang=2
where f1.rang=1

Count number of records returned by temp table - SQL Server

My script is as below
CREATE TABLE #t (Id int, Name varchar(10))
INSERT INTO #t VALUES (1, 'A')
INSERT INTO #t VALUES (1, 'B')
INSERT INTO #t VALUES (1, 'C')
INSERT INTO #t VALUES (1, 'D')
INSERT INTO #t VALUES (2, 'E')
SELECT COUNT(0)FROM (SELECT COUNT(0) FROM #t GROUP BY Id) a
but I am getting an error
Msg 8155, Level 16, State 2, Line 5
No column name was specified for column 1 of 'A'.
When you use a subquery, all the columns need to given names:
SELECT COUNT(0)
FROM (SELECT COUNT(0) as cnt FROM #t GROUP BY Id
) a;
However, a simpler way to write this is:
SELECT COUNT(DISTINCT id)
FROM #t;
Actually, this isn't exactly the same. Your version will count NULL values but this does not. The exact equivalent is:
SELECT COUNT(DISTINCT id) + MAX(CASE WHEN id IS NULL THEN 1 ELSE 0 END)
FROM #t;

Custom ordering in TSQL

I need to implement custom ordering for my table. For example I have a table called "TestTest" with values: a, d01, d04, d02, b . I need to select data and order them so that values with "d" will be first and rest will be sorted alphanumerical. So the result would be d01,d02,d03,a,b
Script to create and insert data:
CREATE TABLE TestTest(
Name varchar(200)
)
DELETE FROM TestTest
INSERT INTO TestTest( Name )
VALUES( 'a' )
INSERT INTO TestTest( Name )
VALUES( 'd01');
INSERT INTO TestTest( Name )
VALUES( 'd04');
INSERT INTO TestTest( Name )
VALUES( 'd02');
INSERT INTO TestTest( Name )
VALUES( 'b' );
Thx for any help ;)
Select *
From TestTest
Order By CASE WHEN LEFT(Name,1)='d' THEN 1 ELSE 2 END,Name
SQL Fiddle Demo
Quick soution:
Select *
from TestTest
order by case when Name like 'd%' then 'aaaaa'+Name else Name end
select * from TestTest order by case when Name='d01' then 1
when Name='d02' then 2
when Name ='d04' then 3
end desc

SQL: How to Transform rows to column in TSQL

Here is table structure, and sample data
create table #tmp ( Id int, Name varchar(100))
insert into #tmp (Id,Name)
Values (1,'Add')
insert into #tmp (Id,Name)
Values (2,'Update')
insert into #tmp (Id,Name)
Values (3,'Delete')
and expected result should be.
Add Update Delete
=== ====== ======
1 2 3
There are several ways that you can transform the data from rows into columns.
If your database has a PIVOT function, then you could use the following code to pivot the data:
select [Add], [Update], [Delete]
from
(
select id, name
from #tmp
) src
pivot
(
max(id)
for name in ([Add], [Update], [Delete])
) piv
See SQL Fiddle with Demo.
Or you could use an aggregate function with a CASE expression:
select
max(case when name = 'Add' then id end) [Add],
max(case when name = 'Update' then id end) [Update],
max(case when name = 'Delete' then id end) [Delete]
from #tmp
See SQL Fiddle with Demo
Please try:
SELECT [Add], [Update], [Delete]
FROM (select * from #tmp) up
PIVOT (sum(id) FOR Name IN ([Add], [Update], [Delete])) AS pvt