Filter out really unique rows - sql

A | B
=====
1 | 2
3 | 4
2 | 1
How can I filter this table and get only unique rows? Something like that:
1 | 2
3 | 4

I think you want something like this:
select a, b
from t
where a <= b
union all
select a, b
from t
where a > b and
not exists (select 1 from t t2 where t2.a = t.b and t2.b = t.a);
Note: This assumes that there are no actual duplicates in your data and you only one to keep one pair, regardless of the ordering.

Use distinct
select distinct least(a,b) as a, greatest(a,b) as b
from the_table;
Or if your DBMS does not support least() and greatest()
select distinct
case when a < b then a else b end as a,
case when a > b then a else b end as b
from the_table;

Simpler version that omits the subquery and handles actual duplicates by leaning on UNION:
SELECT a, b FROM test WHERE a <= b
UNION
SELECT b, a FROM test WHERE a > b;

Related

How to identify non-existing keys with reference to a table that has all mandatory keys, SQL?

I have the table 'Table01' which contains the keys that should be mandatory:
id
1
2
3
4
And I also have the table 'Table02' which contains the records to be filtered:
id
customer
weight
1
a
100
2
a
300
3
a
200
4
a
45
1
b
20
2
b
100
3
b
17
1
c
80
4
c
90
2
d
30
3
d
30
4
d
50
So I want to identify which are the mandatory id's that the table 'Table02' does not have, and in turn identify which is the 'customer' of each id's that the table 'Table02' does not have.
The resulting table should look like this:
customer
id
b
4
c
2
c
3
d
1
What I have tried so far is a 'rigth join'.
proc sql;
create table table03 as
select
b.id
from table02 a
right join table01 b
on a.id=b.id
where a.id is null;
run;
But that query is not identifying all the id's that should be mandatory.
I hope someone can help me, thank you very much.
here is one way:
select cl.customerid , a.id
from
Table1 a
cross join
( select customerid
from table2
group by customerid
) cl
where not exists ( select 1 from table2 b
where b.customerid = cl.customerid
and b.id = a.id
)
You can use an EXCEPT between two sub-selects. The first creates a matrix of all possibilities, and the except table is a selection of the extant customers.
Example:
data ids;
do id = 1 to 4; output; end;
run;
data have;
input id customer $ weight;
datalines;
1 a 100
2 a 300
3 a 200
4 a 45
1 b 20
2 b 100
3 b 17
1 c 80
4 c 90
2 d 30
3 d 30
4 d 50
run;
proc sql;
create table want(label='Customers missing some ids') as
select matrix.*
from
(select distinct have.customer, ids.id from have, ids) as matrix
except
(select customer, id from have)
;
quit;
If you are doing it in SQL server. Something like #eshirvana above posted, but also you can use with cte:
;with cte as
(
SELECT t1.id, t2.Customer
FROM Table01 t1
cross join (select distinct customer from Table02)
)
SELECT a.customer, a.id FROM cte a
LEFT JOIN Table02 b
ON a.id=b.id AND a.customer=b.customer
where b.id is null

Select a record if not sharing a column value with another record

Lets say I have a table of the following form,
X | Y | Z
_________
1 A 3
1 B 3
1 C 4
1 B 4
and I want to query the record which contains B, but only those records that contain B and do not share a common Z field value with a specific record, in this case say A. Thus, ideally the query would return the record "1 B 4".
You could use not exists:
select t.*
from t
where t.y = 'B' and
not exists (select 1 from t t2 where t2.z = t.z and t2.y = 'A');
With indexes on (z, y) and (y) this is likely to be the fastest method as well.

Shows rows with different values for single ID

I have a (part of a) table that looks like this:
Some_ID Some_Value
1 A
2 B
3 C
3 C
3 D
4 E
4 E
4 E
I want to find all rows that has different values per ID, so for this example my output should be:
Some_ID Some_Value
3 C
3 C
3 D
It doesn't even have to look like this, it would also be enough to just get the IDs without the values.
Any ideas?
You could use this:
SELECT some_id
FROM table_name
GROUP BY some_id
HAVING COUNT(DISTINCT some_value) > 1
ORDER BY some_id;
Have a sub-query that returns Some_ID's having more than 1 different Some_Value. JOIN with that result:
select t1.Some_ID, t1.Some_Value
from tablename t1
join (select Some_ID
from tablename
group by Some_ID
having count(distinct Some_Value) > 1) t2
on t1.Some_ID = t2.Some_ID

SQL apply different where condition (filter) for each group in table

i have following SQL table A in my database:
index, group, foo
1 A 2
2 A 2
3 A 0
4 A 1
5 B 2
6 B 1
7 C 1
There are few more groups and I need to write a query based on this filter table B. For each group in table A it's index should be equal or greater than index_egt from table B for the same group.
If the group is not listed in table B, the group won't be filtered.
index_egt, group
3 A
5 B
Expected result:
index, group, foo
3 A 0
4 A 1
5 B 2
6 B 1
7 C 1
Try this, the A.index>=B.index_egt will handle cases where the group is listed in TableB and the B.index_egt IS NULL will handle cases where the group is not listed:
SELECT
A.index,
A.group,
A.foo
FROM TableA AS A
LEFT JOIN TableB AS B ON A.group=B.group
WHERE A.index>=B.index_egt
OR B.index_egt IS NULL
select
a.*
from
A a
left join
B b ON b.group = a.group
where
a.index >= b.index_egt OR b.index_egt IS NULL
I always like this trick with coalesce
SELECT a.*
FROM a_table_with_no_name a
LEFT JOIN b_table_with_no_name b ON b.group = a.group
WHERE a.index >= COALESCE(b.index_egt,a.index)

Which kind of join do I need to use here?

For every row in table Y, I need a copy of the current row in Table X, taking field 1 from Table Y.
Table X
Field 1 Field 2
null A
null B
null C
Table Y
Field 1
1
2
3
Desired output
Field 1 Field 2
1 A
1 B
1 C
2 A
2 B
2 C
3 A
3 B
3 C
Looks like a cross join:
select y.field1, x.field2
from x cross join
y;
Looks like an unconditional select of both tables without matching ids
Something like
select tableY.column1, tableX.column2
from tableY, tableX
order by tableY.column1 asc, tableX.column2 asc
should do it.
BTW. Was this a school question, because then I should not have answered this.
Try this query:
SELECT #Tabley.Field1 , #TableX.Field2
FROM #TableX ,#Tabley