Joining 2 SQL SELECT result sets into one - sql

I've got 2 select statements, returning data like this:
Select 1
col_a col_b
Select 2
col_a col_c
If I do union, I get something like
col_a col_b
And rows joined. What i need is getting it like this:
col_a col_b col_c
Joined on data in col_a

Use JOIN to join the subqueries and use ON to say where the rows from each subquery must match:
SELECT T1.col_a, T1.col_b, T2.col_c
FROM (SELECT col_a, col_b, ...etc...) AS T1
JOIN (SELECT col_a, col_c, ...etc...) AS T2
ON T1.col_a = T2.col_a
If there are some values of col_a that are in T1 but not in T2, you can use a LEFT OUTER JOIN instead.

Use a FULL OUTER JOIN:
select
a.col_a,
a.col_b,
b.col_c
from
(select col_a,col_bfrom tab1) a
join
(select col_a,col_cfrom tab2) b
on a.col_a= b.col_a

SELECT table1.col_a, table1.col_b, table2.col_c
FROM table1
INNER JOIN table2 ON table1.col_a = table2.col_a

Related

Get exclusive users in each table

I have 4 tables as shown below
For each table I want the count of users that are present exclusively in that table (not present in other tables). The result should look something likes this
I have one way of getting desired result as shown below:
First Column:
SELECT COUNT(DISTINCT A.id) table1_only
FROM table1 A
LEFT JOIN (SELECT DISTINCT id
FROM table2
UNION
SELECT DISTINCT id
FROM table3
UNION
SELECT DISTINCT id
FROM table4) B
ON A.id = B.id
WHERE B.id IS NULL
Second Column:
SELECT COUNT(DISTINCT A.id) table2_only
FROM table2 A
LEFT JOIN (SELECT DISTINCT id
FROM table1
UNION
SELECT DISTINCT id
FROM table3
UNION
SELECT DISTINCT id
FROM table4) B
ON A.id = B.id
WHERE B.id IS NULL
Third Column:
SELECT COUNT(DISTINCT A.id) table3_only
FROM table3 A
LEFT JOIN (SELECT DISTINCT id
FROM table1
UNION
SELECT DISTINCT id
FROM table2
UNION
SELECT DISTINCT id
FROM table4) B
ON A.id = B.id
WHERE B.id IS NULL
Fourth Column:
SELECT COUNT(DISTINCT A.id) table4_only
FROM table4 A
LEFT JOIN (SELECT DISTINCT id
FROM table1
UNION
SELECT DISTINCT id
FROM table2
UNION
SELECT DISTINCT id
FROM table3) B
ON A.id = B.id
WHERE B.id IS NULL
But I wanted to know if there is any efficient and scalable way to get same result. Just for 4 tables the amount of code is too much.
Any ways of optimizing this task will be really helpful.
Sample fiddle. (This fiddle is for mysql, I am looking for a generic SQL based approach than any db specific approach)
P.S.:
There is no complusion on the result needs to be in column wise. It can be row wise as well, as shown below:
I would approach this by combining the data from all tables. Then aggregate and filter:
select which, count(*) as num_in_table_only
from (select id, min(which) as which, count(*) as cnt
from ((select id, 1 as which from table1) union all
(select id, 2 as which from table2) union all
(select id, 3 as which from table3) union all
(select id, 4 as which from table4)
) t
group by id
) i
where cnt = 1
group by which
Note: In your sample data, the ids are unique in each table. This solution assumes that is true, but can easily be tweaked to handle duplicates within a table.

select query respecting conditions

i have my table containing 4 Columns (id, val1, val2, val3).
Does anyone knows how to select rows where val3 is the same where val1 is different.
for example
row1: (id1, user1, matheos, cvn)
row2: (id2, user2, matheos, cvn)
row3: (id3, user3, Claudia, bnps)
then i return the row1 and row2.
Your explanation is not entirely clear, but the following query will find matching rows according to the criteria you specified:
select a.*, b.*
from my_table a
join my_table b on b.val3 = a.val3
and b.val2 <> a.val2
and b.id < a.id
In order to produce the rows separately, you can also do:
select *
from my_table a
where exists (
select null from my_table b where b.val3 = a.val3 and b.val2 <> a.val2
)
Based on your explanation, you can try this:
select distinct t1.* from mytable t1
JOIN mytable t2 where t1.val3 = t2.val3
and t1.val1 != t2.val1;
Demo: SQL Fiddle

SQL join with distinct column on one table

Maybe I'm searching using the wrong words because I can't find the answer elswhere, but I need to join two tables but make sure the ID from one of the tables is distinct. Something like the below:
SELECT B.COLUMN_A, B.COLUMN_B, B.COLUMN_C
FROM TABLE1 A
JOIN TABLE2 B
ON (Distinct) A.COLUMN_A = B.COLUMN_A;
The value A.COLUMN_A from TABLE1 needs to be DISTINCT.
I've tried the below but that didn't work:
SELECT B.COLUMN_A, B.COLUMN_B, B.COLUMN_C
FROM TABLE1 A
JOIN (SELECT DISTINCT COLUMN_A FROM TABLE2) B
ON A.COLUMN_A = B.COLUMN_A;
I keep getting a ORA-00904: invalid identifer error on B.COLUMN_C. If I try to use ) AS B then I get a ORA-00905: missing keyword error.
If you don't care about the other values, use group by
SELECT b.column_a, b.column_b, b.column_c
FROM table1 a
JOIN (
SELECT column_a, max(column_b) as column_b, max(column_c) as column_c
FROM table2
GROUP BY column_a
) b ON a.column_a = b.column_a
Use a ROW_NUMBER to get a single row per COLUMN_A:
SELECT *
FROM table1 A
JOIN
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY COLUMN_A ORDER BY COLUMN_A) AS rn
FROM table2
) B
ON A.column_a = B.column_a
AND B.rn = 1
Maybe you need something like this:
select * from
(
select column_a,column_b,column_c
from
(
select column_a,column_b,column_c, count(1) over (partition by column_a) as num
from tableB
)
where num = 1
)tB
inner join tableA
using (column_a)
The double nesting is not necessary, but I hope it makes the query more readable
If you need col_a, col_b, col_c and want to ensure col_a never repeats and col_b, col_c values are not germane, then :
SELECT col_a, col_b, col_c
FROM table2
WHERE rowid in ( SELECT min(rowid)
FROM table2 A , table1 B )
WHERE B.col_a = A.col_a
GROUP BY A.col_a )
In above you choose one distinct row of Table2 that is also present in Table1. Then using that row's id you select all three columns.
You are not selecting any of the columns from TABLE1, so your join to (distinct) TABLE1 records is really just a semi-join, which is most easily expressed as:
SELECT B.COLUMN_A, B.COLUMN_B, B.COLUMN_C
FROM TABLE2 B
WHERE EXISTS ( SELECT 'at least one row in table1'
FROM TABLE1 A
WHERE A.COLUMN_A = B.COLUMN_A );

insert into table without the intersection part

In case I have two SQL tables ,table_a and table_b, both are same , except they may contain different data, I want to insert into the table_b all the rows from table_b that does not exist in table_a already, how should the query look like ? The tables contain id1 and id2 columns only.
Please tell me if my question is not clear
Insert into table_a ...
Thank you
; with cte_left as
(
select id1+id2
from table_a
where id1+id2 not in (select id1+id2 from table_b)
)
insert into table_b
select * from cte_left
You could use the EXCEPT operator:
INSERT INTO table_a (id1, id2)
SELECT id1, id2
FROM (
SELECT id1, id2
FROM table_b
EXCEPT
SELECT id1, id2
FROM table_a
) except_gry
SQL Fiddle demo here
Insert into table_a ( id1, id2 )
select b.id1, b.id2
from table_b b
left outer join table_a a on a.id1 = b.id1 and a.id2 = b.id2
where a.id1 is null
You can use not exist in your query:
insert into table_a(id1,id2)
select id1,id2
from table_b
where not exists(select id1,id2 from table_a)

SQL query to find distinct values in two tables?

Table 1 Table 2
Number | Code Code | Description
1234 A A Something
1235 B C Something else
1246 C D Something other
1247 A
1248 B
1249 A
I would like to find the distinct Code values and get a return like this:
1 | 2
-------
A A
B
C C
D
I can't figure out how to write a SQL query that would return me the above results. Anyone have any experience with a query like this or similar?
In proper RDBMS:
SELECT
T1.Code, T2.Code
FROM
(SELECT DISTINCT Code FROM Table1) T1
FULL OUTER JOIN
(SELECT DISTINCT Code FROM Table2) T2
ON T1.Code = T2.Code
In MySQL... the UNION removes duplicates
SELECT
T1.Code, T2.Code
FROM
Table1 T1
LEFT OUTER JOIN
Table2 T2 ON T1.Code = T2.Code
UNION
SELECT
T1.Code, T2.Code
FROM
Table1 T1
RIGHT OUTER JOIN
Table2 T2 ON T1.Code = T2.Code
In Standard SQL, using relational operators and avoiding nulls:
SELECT Code AS col_1, Code AS col_2
FROM Table_1
INTERSECT
SELECT Code AS col_1, Code AS col_2
FROM Table_2
UNION
SELECT Code AS col_1, 'missing' AS col_2
FROM Table_1
EXCEPT
SELECT Code AS col_1, 'missing' AS col_2
FROM Table_2
UNION
SELECT 'missing' AS col_1, Code AS col_2
FROM Table_2
EXCEPT
SELECT 'missing' AS col_1, Code AS col_2
FROM Table_1;
Again in Standard SQL, this time using constructs that MySQL actually supports:
SELECT Code AS col_1, Code AS col_2
FROM Table_1
WHERE EXISTS (
SELECT *
FROM Table_2
WHERE Table_2.Code = Table_1.Code
)
UNION
SELECT Code AS col_1, 'missing' AS col_2
FROM Table_1
WHERE NOT EXISTS (
SELECT *
FROM Table_2
WHERE Table_2.Code = Table_1.Code
)
UNION
SELECT 'missing' AS col_1, Code AS col_2
FROM Table_2
WHERE NOT EXISTS (
SELECT *
FROM Table_1
WHERE Table_1.Code = Table_2.Code
);
What you're looking for is a full outer join:
select a.code as code_1,b.code as code_2
from(
select code
from table1
group by 1
)a
full outer join(
select code
from table2
group by 1
)b
using(code)
order by 1;
This actually looks like a UNION of two outer joins. Try this:
SELECT t1.Code, t2.Code
FROM Table1 AS t1
LEFT JOIN Table2 AS t2 ON t1.Code
UNION
SELECT t1.Code, t2.Code
FROM Table1 AS t1
RIGHT JOIN Table2 AS t2 ON t1.Code
ORDER BY 1, 2
The UNION operation will only keep distinct values.
The trick would be to get the distinct values from both tables, something like this:
SELECT a.Code, b.code
FROM
( --Get the DISTICT Codes from all sets
SELECT Distinct Code from Table1
UNION SELECT Distinct Code from Table2
) x Left JOIN
Table1 a ON x.code = a.Code LEFT JOIN
Table2 b ON x.code = b.Code
SELECT
ct.ct_id,
ct.pd_id,
ct.ct_qty,
pd.product_name,
pd.price,
src.service_id,
src.service_name,
src.service_charge,
src.service_quantity
FROM
cart ct,
product pd,
service src
WHERE ct_session_id = '$sid'
LIMIT 1