Get Rows from table where column one has same value and column 2 has a different value - sql

I need to find all the rows where col2 has same value but col3 has a different value .From the table above , It should return Pk1,Pk3 and Pk4. I tried the following a self join but i see duplicate records .
SELECT T1.COL1,T1.COL2,T1.COl3
FROM Tab T1, Tab T2
WHERE T1.Col2=T2.Col1
AND T1.Col3 <> T2.Col3
;

I would use exists:
select t.*
from t
where exists (select 1 from t t2 where t2.col2 = t.col2 and t2.col3 <> t.col3);

Analytic functions are better for this kind of job - they avoid all joins. For example:
select col1, col2, col3
from (
select t.*,
case when min(col3) over (partition by col2) !=
max(col3) over (partition by col2) then 0 end as flag
from tab t
)
where flag = 0;
It is not entirely clear how you want to handle null in col3 - does that count as a "different" value? What if you have null more than once (for the same value in col2)? Also - what if col2 can be null?

Try this:
SELECT COL1,COL2,COL3 FROM
(SELECT COL1,COL2,COL3, COUNT(DISTINCT COL3) OVER (PARTITION BY COL2) CNT
FROM TEST)
WHERE CNT > 1
db<>fiddle demo
Cheers!!

Related

Delete Duplicate record in sql server if 2 colums matching

Col1
Col2
Col3
A
B
1
A
B
1
A
B
2
A
B
2
A
c
1
When col1 and Col2 values are same and Col3 values are different I dont want that values in result set.
I want result as below. I tried with row_number, group by , so manythings but did not worked. Please help me here
Col1
Col2
Col3
A
c
1
You can use exists:
delete from t
where exists (select 1
from t t2
where t2.col1 = t.col1 and t2.col2 = t.col1 and
t2.col3 <> t.col3
);
You can also use window functions:
with todelete as (
select t.*,
min(col3) over (partition by col1, col2) as min_col3,
max(col3) over (partition by col1, col2) as min_col4
from t
)
delete from todelete
where min_col3 <> max_col3;
Best way is to make these column a unique composite key. But here is a query to delete all records other than your desired result.
delete from Table_1
where
Col1=(SELECT Col1
FROM table_1
GROUP BY Col1, Col2
HAVING Count(*) > 1)
And
Col2 =(SELECT Col2
FROM table_1
GROUP BY Col1, Col2
HAVING Count(*) > 1)
this might not be the most optimized and efficient query but it works. if you don't want to delete duplicated records and just retrieve unique ones:
SELECT Col1,Col2
FROM table_1
GROUP BY Col1, Col2
HAVING Count(*) = 1
To get duplicating records:
SELECT Col2,Col1
FROM table_1
GROUP BY Col1, Col2
HAVING Count(*) > 1

SQL - avoid select if there is pair

Is it possible to write MS SQL query for this case? If there is pair with 1 and -1 , I don't want select those entries at all.
COL1
COL2
NOTE
A
1
I don't want select this entry becase is in pair with A -1
A
-1
I don't want select this entry becase is in pair with A 1
A
1
OK to select - no pair (no -1 for this A )
B
1
OK to select - no pair
C
1
OK to select - no pair
D
1
I don't want select this entry because is in pair with D -1
D
-1
I don't want select this entry because is in pair with D 1
I understand there is 1s and -1s and these are the only possible values for col2. If this is the case and there is at most one row difference, then you can just add the values up:
select col1, sum(col2)
from mytable
group by col1
having sum(col2) <> 0;
If there can be more rows different or there exist other values beside 1 and -1, then we must generate row numbers.
select col1, max(col2)
from
(
select
col1,
col2,
row_number() over (partition by col1, col2 order by col2) as rn
from mytable
) numbered
group by col1, rn
having count(*) = 1;
One method is aggregation. Assuming there are only -1 and 1 and no duplicates with the same sign:
select col1, max(col2), col3
from t
group by col1, col3
having count(*) = 1;
Alternatively, you could use `not exists:
select t.*
from t
where not exists (select 1
from t t2
where t2.col3 = c.col3 and t2.col1 = t.col1 and
t2.col2 = - t.col1
);
If for any value of Col1 sum of 1 and -1 is not 0, it means that it has unpaired value.
try this:
select *
from t
where col1 in
(select col1 from t group by col1 having sum(col2) <> 0);

How to find records with duplicate values for some specific columns only in oracle PL/SQL

I work in PL/SQL Developer with Oracle.
I have this simple SQL query below:
select
col1
col2,
col3,
col4,
col5
from table t1
(condition required)
and col1=X or col=X or...
and I want to select all different records having col2 and col3 with identical values.
For example:
Record 1: col2=5 col3=orange Record 2: col2=5 col3=orange Record 3:
col2=8 col3=apple Record 4: col2=8 col3=apple
Use analytic functions:
select t.*
from (select t.*, count(*) over (partition by col2, col3) as cnt
from t
) t
where cnt > 1
order by col2, col3;
select
t1.col1
t1.col2,
t1.col3,
t1.col4,
t1.col5
from table t1
join table t2 on t1.col2 = t2.col2 and t1.col3 = t2.col3 and t1.rowid <> t2.rowid
where ...
;
If you have a primary key column on the table, use that instead of rowid.

Oracle: Alternative to sub-query

Is there an alternative to re-write the below oracle query without using sub-queries
SELECT COL1,COL2 FROM TABLE WHERE COL2 IN (SELECT MAX(COL2) FROM TABLE)
Edit: There is only 1 table with COL1 and COL2 where the row with maximum value of
COL2 is the expected output
SELECT COL1,COL2
FROM TABLE
ORDER BY COL2 DESC
FETCH FIRST 1 ROW WITH TIES
This one should also work:
SELECT MAX(COL1) KEEP (DENSE_RANK LAST ORDER BY COL2) as COL1,
MAX(COL2) as COL2
FROM TABLE;
Use PARTITION key find out maximum col2 with col1 as per below:
select COL1, COL2 from (
select COL1, COL2, ROW_NUMBER() over(PARTITION BY COL1 ORDER BY COL2 desc) row_num from TABLE
) where row_num=1;
Assuming COL1 can be used as candidate key -
SELECT T1.COL1,
T1.COL2
FROM TABLE1 T1
INNER JOIN TABLE1 T2
ON (T1.COL1 = T2.COL1
AND T1.COL2 >= T2.COL2)

SQL query to simulate distinct

SELECT DISTINCT col1, col2 FROM table t ORDER BY col1;
This gives me distinct combination of col1 & col2. Is there an alternative way of writing the Oracle SQL query to get the unique combination of col1 & col2 records with out using the keyword distinct?
Use the UNIQUE keyword which is a synonym for DISTINCT:
SELECT UNIQUE col1, col2 FROM table t ORDER BY col1;
I don't see why you would want to but you could do
SELECT col1, col2 FROM table_t GROUP BY col1, col2 ORDER BY col1
Another - yet overly complex and somewhat useless - solution:
select *
from (
select col1,
col2,
row_number() over (partition by col1, col2 order by col1, col2) as rn
from the_table
)
where rn = 1
order by col1
select col1, col2
from table
group by col1, col2
order by col1
or a less elegant way:
select col1,col2 from table
UNION
select col1,col2 from table
order by col1;
or a even less elegant way:
select a.col1, a.col2
from (select col1, col2 from table
UNION
select NULL, NULL) a
where a.col1 is not null
order by a.col1
Yet another ...
select
col1,
col2
from
table t1
where
not exists (select *
from table t2
where t2.col1 = t1.col1 and
t2.col2 = t1.col2 and
t2.rowid > t1.rowid)
order by
col1;
Variations on the UNION solution by #aF. :
INTERSECT
SELECT col1, col2 FROM tableX
INTERSECT
SELECT col1, col2 FROM tableX
ORDER BY col1;
MINUS
SELECT col1, col2 FROM tableX
MINUS
SELECT col1, col2 FROM tableX WHERE 0 = 1
ORDER BY col1;
MINUS (2nd version, it will return one row less than the other versions, if there is (NULL, NULL) group)
SELECT col1, col2 FROM tableX
MINUS
SELECT NULL, NULL FROM dual
ORDER BY col1;
Another ...
select col1,
col2
from (
select col1,
col2,
rowid,
min(rowid) over (partition by col1, col2) min_rowid
from table)
where rowid = min_rowid
order by col1;