Select new column based on existing value - sql

I have sample data like below
create Table #Temp(id int, Data1 varchar(10), Data2 bigint)
Insert Into #Temp
Values(1,'Value1',109040774),
(2,'Value2',10000006099758),
(3,'Value3',10000006099758),
(4,'Value1',14538),
(5,'Value2',10000006097458),
(6,'Value3',10000006097458),
(7,'Value1',4454834),
And trying to select new column based on Data1, so the output will be
id Data1 NewColumn
1 Value1 109040774
2 Value2 109040774
3 Value3 109040774
4 Value1 14538 --reset here because same value of Data1 (Value 1 started repeating)
5 Value2 14538
6 Value3 14538
7 Value1 4454834 --reset here because same value of Data1 (Value 1 started repeating)
I was trying to use something like below, but not what I after
SELECT id, Data1,
FIRST_VALUE(Data2) OVER (Partition by Data1 ORDER BY Id ASC) AS NewCol
FROM #Temp
Order By Id
Any help is appreciate

Here is my idea assuming a special value1 defines a new group:
Use a cumulative sum to calculate the number of value1s on or before each row.
This defines a grouping.
Within each group, use first_value().
Hence:
select t.id, t.data1,
first_value(data2) over (partition by grp order by id) as newcolumn
from (select t.*,
sum(case when data1 = 'value1' then 1 else 0 end) over (order by id) as grp
from t
) t;

Related

Sql Group by Value1 having count(*) > 1 but with different value 2

Given an SQL table like this
id value1 value2
---------------
1 1 1
2 1 1
3 1 1
4 2 1
5 2 2
6 3 1
I want to find all the value1's that have duplicate value1 (i.e using group by having count(*)>1) but only if they have different values for value2
So in this example I just want to return 2
Im using Postgres
If I understand correctly, this is group by with a having clause:
select value1
from t
group by value1
having min(value2) <> max(value2)
use
select * from ( select * , ROW_NUMBER() OVER(PARTITION BY Value1 ORDER BY Value1 , Value2 ASC) AS RowValue1, ROW_NUMBER() OVER(PARTITION BY Value1 , Value2 ORDER BY Value1 , Value2 ASC) AS RowValue2 from Table_1 ) As TableTmp where TableTmp.RowValue1 <> TableTmp.RowValue2
Or
select * from Table_1 where value1 in (select value1 from Table_1 group by value1 having min(value2) <> max(value2) )

hive - Top N with multiple measurements in one query?

The sample table
value measurement1 measurement2
-------|-------------|-----------
value1 1 **2**
value2 **3** **3**
value3 **2** 1
Then find top 2 highest value,
I want to get the output below:
top 2 by measurement1 top 2 by measurement2
---------------------|----------------------
value2 value2
value3 value1
You can do this using row_number() and join:
select s1.value1 as col1,
s2.value2 as col2
from (select s.*,
row_number() over (order by value1) as seqnum
from sample s
) s1 join
(select s.*,
row_number() over (order by value2) as seqnum
from sample s
) s2
on s1.seqnum = s2.seqnum
where s1.seqnum <= 2
order by s1.seqnum;

Pivot table in teradata sql

I have data like this:
ID Result
1 value1
2 value1
2 value2
3 value1
4 value1
4 value2
4 value3
How can I accomplish in teradata SQL the pivot table like in Excel.
ID Value1 Value2 ...
1 count of Value1 for ID 1 count of Value2 for ID 1 ...
2 count of Value1 for ID 2 count of Value2 for ID 1 ...
3 ... ... ...
assuming that there is a large number of ID and varying number of Values.
SELECT sum(case when Result='Value1' then ID end) "Value1"
, sum(case when Result='Value2' then ID end) "Value2"
FROM your_table
GROUP BY null;
Not much context can be added here I'm afraid, except this is the way pivots can be implemented in TD up to v15.x
So i found the answer and i would like to share it with you
First of all you need to recalculate the data to know the counts for id||Value
CREATE TABLE myTable_count as (
SELECT ID, Result, count(1) as countOfResult
FROM myTable
group by ID, Result
) WITH DATA
Then you can do a pivot, but you have to know the names of result's
SELECT ID,
sum(CASE WHEN Result='Value1' then countOfResult else NULL END) Value1,
sum(CASE WHEN Result='Value2' then countOfResult else NULL END) Value2
FROM myTable_count
GROUP BY ID;
If it help you give it a vote up.
SELECT
id,
count(
CASE WHEN result1 = 'value1' THEN id END
) AS value1,
COUNT(
CASE WHEN result1 = 'value2' THEN id END
) AS value2,
COUNT(
CASE WHEN result1 = 'value3' THEN id END
) as value3
FROM
pivot_tb1
group by
1;

Group Count in T/SQL

Source:
CREATE TABLE #TempTab (Value INT, Value1 varchar(10), Value2 varchar(10),
GRP varchar(10))
INSERT INTO #TempTab
SELECT 1,'One','One','One'
UNION ALL
SELECT 1,'One','One','One'
UNION ALL
sELECT 1,'One','One','Two'
UNION ALL
SELECT 2,'One','One','One'
UNION ALL
SELECT 2,'One','One','Two'
UNION ALL
SELECT 2,'One','One','Three'
UNION ALL
SELECT 3,'One','One','One'
UNION ALL
SELECT 3,'One','One','One'
Current query effort:
SELECT Value, Value1, Value2, GRP
, COUNT(1) OVER(PARTITION BY Value, Value1, Value2) CNT
, ROW_NUMBER() OVER(PARTITION BY Value, Value1, Value2, GRP ORDER BY Value) RN
, CASE
WHEN COUNT(*) OVER (PARTITION BY Value, Value1, Value2, GRP) > 1 THEN 1
ELSE 0
END IsMultiple
FROM #TempTab
DROP TABLE #TempTab
Current output:
Value Value1 Value2 GRP CNT RN IsMultiple
1 One One One 3 1 1
1 One One One 3 2 1
1 One One Two 3 1 0
2 One One One 3 1 0
2 One One Two 3 1 0
2 One One Three 3 1 0
3 One One One 2 1 1
3 One One One 2 2 1
Desired output:
Value Value1 Value2 GRP CNT RN IsMultiple NoUniqueGRPed
1 One One One 3 1 1 2
1 One One One 3 2 1 2
1 One One Two 3 1 0 2
2 One One One 3 1 0 3
2 One One Two 3 1 0 3
2 One One Three 3 1 0 3
3 One One One 2 1 1 1
3 One One One 2 2 1 1
Goal:
I am trying to derive a field called NoUniqueGRPed. This field is
basically count of unique grouped records based on Value, Value1, and
Value2 fields. i.e. Value = 1, Value1 = One, and Value2 = One has
three records but two unique GRP values (One and Two) so NoUniqueGRPed
should be 2.
I'm having trouble trying to figure out how to do the unique
aggregation/grouping.
You can try qith cross apply:
SELECT ...,
ca.NoUniqueGRPed
FROM #TempTab t1
CROSS APPLY(SELECT COUNT(DISTINCT GRP) AS NoUniqueGRPed
FROM #TempTab t2
WHERE t1.Value = t2.Value)ca
You can do this directly with window functions:
select tt.*,
count(distinct grp) over (partition by value, value1, value2) as NewColumn
from #TempTab tt
EDIT:
I though that limitation had been fixed. Alas. You can do this using a combination of sum() and row_number():
select tt.*,
sum(case when seqnum = 1 then 1 else 0 end) over (partition by value, value1, value2) as NewColumn
from (select tt.*, row_number() over (partition by value, value1, value2, grp order by grp) as seqnum
from #TempTab tt
) tt

teradata sql pivot multiple occurrences into additional columns

I have something like this:
ID Result
1 value1
2 value1
2 value2
3 value1
4 value1
4 value2
4 value3
And I'd like to return something like this:
ID Result1 Result2 Result3
1 value1
2 value1 value2
3 value1
4 value1 value2 value3
I've searched on pivots and concats and breaks and I just can't find a simple, sensible solution.
TIA
Unfortunately Teradata doesn't have a PIVOT function but you can use an aggregate function with a CASE expression to get the result.
select id,
max(case when seq =1 then result end) result1,
max(case when seq =2 then result end) result2,
max(case when seq =3 then result end) result3
from
(
select id, res, row_number() over(partition by id order by result) seq
from yourtable
) d
group by id
order by id;
If you have more values for each ID, then you can add more CASE expressions.