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) )
Related
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;
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;
I would like to transform a table from rows to columns in SQL Server.
Given table1:
id value1 value2
1 name1 9
1 name1 26
1 name1 15
2 name2 20
2 name2 18
2 name2 61
I need a table like:
id name1 name2
1 9 0
1 26 0
1 15 0
2 0 20
2 0 18
2 0 61
Can pivot help here? An efficient way is preferred to do the convert because the table is large.
I have tried:
select
id, name1, name2
from
(select
id, value1, value2
from table1) d
pivot
(
max(value2)
for value1 in (name1, name2)
) piv;
But, it cannot provide all rows for same ID to combine with 0s.
Thanks
The 'secret' is to add a column to give uniqueness to each row within your 'nameX' groups. I've used ROW_NUMBER. Although PIVOT requires an aggregate, with our 'faked uniqueness' MAX, MIN etc will suffice. The final piece is to replace any NULLs with 0 in the outer select.
(BTW, we're on 2014 so I can't test this on 2008 - apologies)
SELECT * INTO #Demo FROM (VALUES
(1,'name1',9),
(1,'name1',26),
(1,'name1',15),
(2,'name2',20),
(2,'name2',18),
(2,'name2',61)) A (Id,Value1,Value2)
SELECT
Id
,ISNULL(Name1, 0) Name1
,ISNULL(Name2, 0) Name2
FROM
( SELECT
ROW_NUMBER() OVER ( PARTITION BY Id ORDER BY Id ) rn
,Id
,Value1
,Value2
FROM
#Demo ) A
PIVOT ( MAX(Value2) FOR Value1 IN ( [Name1], [Name2] ) ) AS P;
Id Name1 Name2
----------- ----------- -----------
1 9 0
1 26 0
1 15 0
2 0 20
2 0 18
2 0 61
you can do case based aggregation with group by
SQL Fiddle
select id,
max(case when value1 ='name1' then value2 else 0 end) as name1,
max(case when value1 ='name2' then value2 else 0 end) as name2
from Table1
group by id, value1, value2
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
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.