How to compare 2 SQL table for difference - sql

given the following table, how can I have the difference between the 2 tables giving the fact that T143 has every rows duplicated:
T001.CODE T143.CODE
---- -----
A1 A1
A1
A2 A2
A2
A3
A4 A4
A4
Result should be A3 as its only present in T001 - I also need to display all column from T143.
Here's what I have do far but after a manual check of data there is mistake:
SELECT CODE FROM T001
EXCEPT
SELECT CODE FROM T143
thanks

A Full outer join should do the trick
SELECT DISTINCT COALESCE(T001.CODE,T143.CODE), T143.*
FROM T001 FULL OUTER JOIN T143
ON T001.CODE = T143.CODE
WHERE T001.CODE IS NULL OR T143.CODE IS NULL
EDIT: Since DISTINCT is mentioned in the tags, i added it to the query

You can always do this using exists:
select t1.code
from t001 t1
where not exists (select 1 from t143 t2 where t2.code = t1.code);
If you also want the columns from t2, then use union all to get them.
If you want all codes in both tables, just do:
select t1.code
from t001
union -- on purpose for duplicate removal
select t2.code
from t143;

Related

Select entries that have non repeating values on a specific column (although other columns may have repeating or non repeating values) (SQL)

Let's say I have the following table:
A
B
C
D
a1
b1
c1
d1
a1
b1
c1
d2
a2
b2
c3
d3
a2
b2
c4
d3
I want to filter and see all four columns for entries that have the same value con column A but different on column C, so I get only this as a result:
A
B
C
D
a2
b2
c3
d3
a2
b2
c4
d3
I don't really care if values con columns B and D are the same or different, although I would like to have them in my table to do further analysis later.
Using the DISTINCT statement would give me all the columns as a result, as they all are different in some column, so that doesn't work for me.
I read some questions (like this one) and the answers recommended using the row_number() over(partition by...) clause, although the use they gave it doesn't quite fit my problem (I think), as it would also return the first row with a repeating value on column C.
Any ideas how this could be done?
You can use exists:
select t.*
from t
where exists (select 1
from t t2
where t2.a = t.a and t2.c <> t.c
)
order by t.a;
You could use a self join
select t1.*
from t t1
join t t2 on t1.a=t2.a and t1.c<>t2.c

Aggregate and concatenate from two tables based on comparison between columns

I have two tables like this:
Table1
A T
a1 t1
a2 t2
a3 t3
a4 t4
a5 t5
...
...
Table2
E T
e1 t1
e2 t2
e3 t3
e4 t4
e5 t5
...
...
what I wanted to achieve is this:
Table 3
E A'
e1 a1,a2,a3
e2 a4,a5,a6
...
...
The aggregation A' is done like this: In table 2 for each e there is a value in column T : t and with that t you look for the last 3 values in Table 1 that are less than the t in question. So a1, a2, a3 are values of A whose t values are less than t1 in Table 2 whose E is e1.
I know that I could write two queries for this like this:
ResultSet (rt) -> select t from e
and then iterate ResultSet and do something like this :
select A from Table1 where t < rt[i] limit 3 - not sure how to concatenate here :)
but I m pretty sure this is utterly inefficient. There should be a better way to do this.
I m working with Postgresql.
If it had been a dataframe from a file I would use python's pandas. Also I know that python has read_sql but the tables are very huge I don't want to load the whole table in memory which I think it won't but not sure either - anyway its a separate story.
How do we solve this in SQL? Any ideas please.
In table 2 for each e there is a value in column T : t and with that t you look for the last 3 values in Table 1 that are less than the t in question.
I don't understand the results follow this logic. But based on your description, you can use a lateral join:
select t2.*, t1.the_as
from t2 left join lateral
(select array_agg(t1.a) as the_as
from (select t1.*
from t1
where t1.T <= t2.T
order by t1.T desc
limit 3
) t1
) t1
on 1=1;
Note that this uses arrays rather than strings because I think arrays are a better data structure for storing multiple values. That said, you can just use string_agg() instead, if you really want a string. The syntax would be string_agg(t1.a, ',').

combine two oracle sql results into single dataset

I have two selects and I want to combine them in such a way, that only one row that has key column matched in both selects are returned(one row in first select and one row in 2nd select). Is there any built-in way in Oracle 10g to achieve this?
I have two sql as below
Query 1:
select c11, c12 from table t1
where c11=1000
Query 2:
select c21, c22
from t2
where c21=1000
I want to combine both query 1 and query 2 on key columns(OPTYREVN_OPTY_XI, OPTYREVN_SEGMENT_XI and OPTYREVN_OPTYREVNCRM_ID). My output should contain only the only one row which found in results of query 1 and query 2.
I am not sure to use UNION or Intersect or left outer join.
Kindly suggest me some solution which will be helpful in this scenario. Thanks.
So, If I got you right, you want to have c1 , c2 , c33 , c21 , c22 and c 23 on one line, if both queries return only one line and no information can link them, this should work...
SELECT a.* , b.*
FROM (select c1, c2, c33
from t1, t3
where c1= 1000 and c33 is null) a ,
(select c21, c22, c23
from t2
where c21= 1000) b
/*WHERE...*/ --you could always use some condition linking a and b
I think you would want to use a join:
SELECT c1, c2, c33, c21, c22, c23
FROM t1 INNER JOIN t3 ON <key columns>
INNER JOIN t2
ON t1.c1 = t2.c21
WHERE t1.c1 = 1000
AND t3.c33 IS NULL;

Inner join Without duplicates, is it possible?

Given these two tables
Table A1 has two rows with the same value 'a'
A1
a
a
Table A2 has two rows with primary key value A,B and they are associated with 'a'
A2
PK col2
A a
B a
What I want is a join of A1 and A2 with this result
a A
a B
Obviously inner join doesn't work here. Is there a way to do this in SQL Server 2008?
You can wipe out the duplicates by using DISTINCT
select distinct
A1.col1,
A2.PK
from
A1
inner join A2
on A1.col1 = A2.col2
If distinct is not restricted
SELECT DISTINCT a.*, b.pk
FROM A1 a
INNER JOIN A2 b ON (a.[test] = b.fk)
There are no joining condition in the post, so we need to go for cross join. I have applied cross join and restrict the duplicate values using distinct.
Select distinct A1.Col1, A2.Pk
From A1 ,A2
"and restrict the duplicate values using distinct."
at least in Postgres 9+ DISTINCT eliminates existing duplicates but not preventing or restricting its appearing.
SELECT DISTINCT A.*
FROM aTable AS A
INNER JOIN
bTable AS B USING(columnId)

Compare Every Record from Two Tables

Assuming I have two SQL tables consisting of a single column,
i.e.
Table 1 Table 2
a1 a2
b1 b2
c1 c2
Is there a succinct SQL command to compare each record in one table against each record in the other? (and return true if any record from table 1 matches any record from table 2)
i.e.
if( a1 = a2 OR a1 = b2 OR a1 = c2 OR b1 = a2 OR b1 = b2...)
I want
If any record from table a matches table b (i.e., in a table of ints, they are the same int), return true.
Why not simply
if exists (select 1 from T1 inner join TB on T1.Col = T2.Col)
A full join is well suited to finding differences. To find rows that are missing in either table:
select *
from t1
full join
t2
on t1.col1 = t2.col1
where t1.col1 is null
or t2.col1 is null
This assumes that the single column is unique (i.e. has no duplicate values.)