transposing rows to columns in teradata - teradata

I have a table like below
Date_value| Class_ID | count
17-05-2016|1 | 200
17-05-2016|2 | 400
17-05-2016|3 |250
17-05-2016|4 | 300
18-05-2016|1 | 500
18-05-2016|2 | 600
18-05-2016|3 |750
18-05-2016|4 | 800
Now I want the output like below.
Date_value|1 |2 |3 |4
17-05-2016|200 |400 | 250 |300
18-05-2016|500 |600 | 750 |800
Thanks in Advance,
Nikhila

There's no PIVOT function in Teradata, but this is just some syntax which creates a Select similar to this:
select
Date_value,
sum(case when Class_ID = 1 then "count" end as "1",
sum(case when Class_ID = 2 then "count" end as "2",
sum(case when Class_ID = 3 then "count" end as "3",
sum(case when Class_ID = 4 then "count" end as "4",
from tab
group by Date_value

Related

Convert columns to rows Teradata

I need convert columns to rows in Teradata without TD_UNPIVOT. My table
ID |Code_1 | Code_2 | Code_3 | Code_4|
1 |1000 | 2000 | 3000 | 4000 |
1 |1000 | 2000 | 3000 | NULL |
1 |1000 | 2000 | NULL | NULL |
1 |1000 | NULL | NULL | NULL |
I need to convert Code_1, Code_2, Code_3, Code_4 to 2 columns: first column will have all Code_n (without NULL), second one will have Level of Code:
ID | Code_n | Level_of_Code
1 | 4000 | 4
1 | 3000 | 3
1 | 2000 | 2
1 | 1000 | 1
It means, than I should know when Code has NULL (in which level Code_1, Code_2, Code_3 or Code_4 and after that convert it to columns with numbers of max level where I have not NULL).
Please help me.
Thank you
You can produce rows by using multiple select statements and doing a union all to concatenate them together.
Select id, code_1 as "code_n", 1 as "level_of_code" from your table
Union all
Select id, code_2,2
Union all
Select id, code_3,3
Union all
Select id, code_4,4;

distinct values as new columns & count

I'm trying to generate a summary from a table using SQLite as below.
I need to aggregate 1) number of times each model was driven, 2) total distance driven & 3) get distinct values for driver col & count the number of times each driver has driven the particular model - GROUP BY modelwith COUNT(model) & SUM(distance) will help with 1 & 2 - `I need help with the last part #3 , what is the right approach to find number of occurrences for each distinct values of a column and add them as new columns for each model ?
My table is:
id model datetime driver distance
---|-----|------------|--------|---------
1 | S | 04/03/2009 | john | 399
2 | X | 04/03/2009 | juliet | 244
3 | 3 | 04/03/2009 | borat | 555
4 | 3 | 03/03/2009 | john | 300
5 | X | 03/03/2009 | juliet | 200
6 | X | 03/03/2009 | borat | 500
7 | S | 24/12/2008 | borat | 600
8 | X | 01/01/2009 | borat | 700
Result would be
id model| drives distance john juliet borat
---|-----|--------|---------|------|------ |------
1 | S | 2 | 999 | 1 | 0 | 1
2 | X | 4 | 1644 | 0 | 2 | 2
3 | 3 | 2 | 855 | 1 | 0 | 1
OK... this time I got it!
select new_table.model, count (new_table.model) as drives, sum (new_table.distance) as distance,
sum(case when driver = 'john' then 1 else 0 end) as john,
sum(case when driver = 'juliet' then 1 else 0 end) as juliet,
sum(case when driver = 'borat' then 1 else 0 end) as borat
from new_table
group by model
It's not 100%, but this should get you most of the way there.
CREATE TABLE DBO.TEST_TABLE (ID INT,MODEL CHAR(1),DATETIME VARCHAR(255),DRIVER VARCHAR(255),DISTANCE INT)
INSERT INTO DBO.TEST_TABLE
VALUES
(1,'S','04/03/2009','JOHN',399)
,(2,'X','04/03/2009','JULIET',244)
,(3,'3','04/03/2009','BORAT',555)
,(4,'3','03/03/2009','JOHN',300)
,(5,'X','03/03/2009','JULIET',200)
,(6,'X','03/03/2009','BORAT',500)
,(7,'S','24/12/2008','BORAT',600)
,(8,'X','01/01/2009','BORAT',700)
Declare #Query_ nvarchar(MAX)
Declare #Cols_For_Pivot_ nvarchar(MAX)
SELECT #Cols_For_Pivot_= COALESCE(#Cols_For_Pivot_ + ',','') + QUOTENAME(DRIVER)
FROM (SELECT DISTINCT DRIVER FROM DBO.TEST_TABLE) AS PivotTable
IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL DROP TABLE #TEMP
SET #Query_ =
N'SELECT DISTINCT
MODEL
,COUNT(DATETIME) OVER(PARTITION BY MODEL) AS DRIVES
,SUM(DISTANCE) OVER(PARTITION BY MODEL) AS DISTANCE
, ' + #Cols_For_Pivot_ + '
INTO #TEMP
FROM DBO.TEST_TABLE
PIVOT(COUNT(DRIVER)
FOR DRIVER IN (' + #Cols_For_Pivot_ + ')) AS P'
EXEC sp_executesql #Query_

update table in sorted order

I am maintaining table structure like below.
sortid | id | name
1 | 1 | aa
3 | 2 | cc
4 | 3 | cc
2 | 4 | bb
5 | 5 | dd
Where sortid is maintained according to ascending order of name.
Now I want to update name 'dd' to 'aa', such way that sort id is also updated to its correct value.
Update table set name="bb" where name like "dd";
After updating my table should become like below.
sortid | id | name
1 | 1 | aa
4 | 2 | cc
5 | 3 | cc
3 | 4 | bb
2 | 5 | aa
That sortid is the number of rows that would be sorted before this row.
So you can compute it by counting rows:
UPDATE MyTable
SET sortid = (SELECT COUNT(*)
FROM MyTable AS T2
WHERE T2.name < MyTable.name) +
(SELECT COUNT(*)
FROM MyTable AS T2
WHERE T2.name = MyTable.name
AND T2.id <= MyTable.id);
(The second subquery resolves duplicate sortid values that would result from duplicate names.)

SQLITE get row continous value

I have a simple table. One of the example rows looks like this:
id | name |
1 | a |
2 | a |
3 | a |
4 | b |
6 | b |
7 | a |
8 | a |
I want to get last continuous id.
so if i start at '1', the result should be '4'
in this example, the result should be '7'
3 |a |
4 |b |
5 |a |
6 |a |
7 |a |
10|a |
Only i now is that select all after my input number, and find continuous programmatically.
how can i do..?
If I understand the question correctly, this should work for you:
select id from tableName t1 where not exists(select id from tableName t2 where t2.id=t1.id+1) and (id-(select count(*) from tableName t3 where t3.id<t1.id))=(select min(id) from tableName);
If you want to start from 10, it should be:
select id from tableName t1 where not exists(select id from tableName t2 where t2.id=t1.id+1) and (id-(select count(*) from tableName t3 where t3.id<t1.id and t3.id>=10))=10;

Using Ifnull in Subquery SQLite

I've this two tables, members and water_meter
members
id | name
=========
1 | Dani
2 | Dina
3 | Roni
water_meter
id | member_id | date | start | finish | paid | paid_at
===+============+===========+=======+===========+=======+=====================+
1 | 1 |2014-07-01 | 12.3 | 38.7 | 1 | 2014-12-29 18:28:30
2 | 2 |2014-07-01 | 57.2 | 64.3 | 0 | null
3 | 3 |2014-07-01 | 14.6 | 52.3 | 0 | null
This member need to pay their water usage every month. What I want is, the 'start' value of each month is the 'finish' value from previous months. This is my query to check water usage at August,
SELECT m.id, m.name,
ifnull(t.start, (SELECT ifnull(finish, 0) FROM members m2
LEFT JOIN water_meter t2 ON m2.id = t2.member_id AND t2.date = '2014-07-01') ) as start,
t.finish, paid
FROM members m
LEFT JOIN water_meter t ON m.id = t.member_id AND t.date = '2014-08-01'
Result :
id | name | start | finish |
===+========+========+=========+
1 | Dani | 38.7 | null |
2 | Dina | 38.7 | null |
3 | Roni | 38.7 | null |
As you can see, the "start" value is not right. What is the right query for this case?
What I want is like this
id | name | start | finish |
===+========+========+=========+
1 | Dani | 38.7 | null |
2 | Dina | 64.3 | null |
3 | Roni | 52.3 | null |
Check : http://sqlfiddle.com/#!7/29a4c/2
You haven't assigned correct where condition in inner query.
SELECT m.id, m.name,
ifnull(t.start,
(SELECT ifnull(finish, 0) FROM members m2
LEFT JOIN water_meter t2
ON m2.id = t2.member_id AND t2.date = '2014-07-01'
where m2.id = m.id)) as start,
t.finish, paid
FROM members m
LEFT JOIN water_meter t ON m.id = t.member_id AND t.date = '2014-08-01'
WHERE m.active = 1
I don't like query itself, but that produces the output you wanted.
A little better (no subqueries, which may be slow on large dataset) solution:
select
members.id,
name,
coalesce(wm_cur.start, wm_prev.finish),
wm_cur.finish
from members
left join water_meter wm_cur
on members.id = wm_cur.member_id
and wm_cur.date between '2014-08-01' and date('2014-08-01','start of month','+1 month','-1 day')
left join water_meter wm_prev
on members.id = wm_prev.member_id
and wm_prev.date between '2014-07-01' and date('2014-07-01','start of month','+1 month','-1 day')
where members.active = 1
You can replace coalesce with ifnull if you wish. It also handles entire month and not only first day, which may or may not be what you want it to be.

Resources