Join between two tables, number of row - sql

I hope you're well.
I try to write a sql query with a join between two tables like below :
table1 (id_master, id)
1,1
1,2
1,3
1,4
1,5
And the second table
table2 (id_master, id)
1,1
1,2
1,3
1,4
As you can see, each table contain ID_master & id.
The table2 contains the acknownledgement (ack) of table1. Each row in the table1 must have an "ack" in the table2.
In my example, I have no result because (table1 (1,5) hasn't got an ack in table2 and I want result when table1.row (1,5) has got a ack in table2.
I have tried with join but i have result when we have the first "ack". I want have result when I have all "ack".
I hope to be clear.
thanks for your help.
kind regards
EDIT :
Thanks stripathi & jpw,
Example1:
table1 (id_master, id)
1,A
1,B
1,C
2,D
2,E
the second table
table2 (id_master, id)
1,A
1,B
2,D
2,E
My query's result must be :
2,D
2,E
Because we can find the rows(2,D) & (2,E) in the two tables, but it isn't the case for (1,*) (it miss the (1,C) in the table2).

I think both of these two queries should do what you want, and they seem to work using Oracle 11g R2 (see this SQL Fiddle). Note that the result might be wrong if the second table contains items that are not present in the first table.
select *
from table1
where id_master in (
select a.id_master
from table1 a
group by a.id_master
having count(distinct a.id) = (
select count(distinct b.id)
from table2 b
where a.id_master = b.id_master
group by b.id_master
)
);
select *
from table1 a
where not exists (
select id from Table1 where id_master = a.id_master
minus
select id from Table2
);

If you using oracle you can use ROWNUM to get row number of first ack. You can try this :
SELECT ID,ID_MASTER FROM(
SELECT ID,ID_MASTER,ROWNUM RR
FROM TABLE2
ORDER BY ID_MASTER,ID ASC) T2
WHERE RR >= (
SELECT R FROM(
SELECT ID_MASTER,ID, ROWNUM R
FROM TABLE1
ORDER BY ID_MASTER,ID ASC
) T1
WHERE T1.ID_MASTER||T1.ID NOT IN(SELECT ID_MASTER||ID FROM TABLE2)
)

Related

How to combine multiple SELECT statements into a single query & get a single result output

I have multiple SELECT queries which is ran against different tables.
The output of all the queries have the same number of rows (every query when ran individually will have the same number of rows). Is there a way I can combine the output of all these queries into a single result? (Keep out from first query and add the output of next query as a column to the output of the next query). I dont want to save these tables into database as I am just doing some validation testing.
Example:
SELECT AAA,BBB,CCC FROM Table1
SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
I tried writing combining the query as
SELECT Table1.AAA,Table1.BBB,Table1.CCC,T1.DDD
FROM Table1,
(SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA)T1
I tried doing the above combined query, but instead of getting 11 rows as output (both queries above had result of 11 rows), I am getting 35 rows as output.
Hope the question made sense!
You'll need to specify a criteria to match each row the first query with which row of the second query.
If, for example, the column AAA is unique in both queries and you want to match rows with the same values you could do:
select a.*, b.*
from (
SELECT AAA,BBB,CCC FROM Table1
) a
full join join (
SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
) b on b.aaa = a.aaa
If there aren't any clear matching rules, you can produce an artificial row number on each result set and use it to match rows. For example:
select
a.aaa, a.bbb, a.ccc,
b.ddd, b.aaa
from (
SELECT AAA, BBB, CCC,
row_number() over(order by aaa) as rn
FROM Table1
) a
full join join (
SELECT Table2.DDD, Table1.AAA,
row_number() over(order by table1.aaa, table2.ddd) as rn
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
) b on b.rn = a.rn
If you have several results and want to have all of them as additional columns you can simply use ",":
create table temp1 as select '1' as c1 from DUAL;
create table temp2 as select '2' as c2 from DUAL;
create table temp3 as select '3' as c3 from DUAL;
select a.c1, b.c2, c.c3 from temp1 a, (select c2 from temp2) b, (select c3 from temp3) c;
An alternative could also be that you want to have all the results as additional rows then you would use UNION ALL between the individual results.

Update only duplicate values in a table column

I have got a table that has a column with duplicate values. I would like to update duplicate values (not the first instance though) by incrementing by 1 so that I can get rid of duplicates in that column.
Can anyone help?
You need ranking on Tel over username. This will give you the ranking.
SELECT *, (select count(table1.username)
from table1 as tbl2
where table1.tel >= tbl2.tel and table1.username=tbl2.username)
as rank from table1 ORDER BY username,tel;
if your active column is always T then you can hard code it in the query as below:
SELECT *, (select count(table1.username) from
table1 as tbl2
where table1.tel >= tbl2.tel and table1.username=tbl2.username) & 'T'
as rank from table1 ORDER BY username,tel
if column active in Table1 can be different, then save the first query as query1 and use this join query:
SELECT Table1.active & query1.rank AS Expr1, Table1.tel, Table1.username
FROM Table1 INNER JOIN Query1 ON Table1.ID = Query1.ID;
add an ID column to your Table1 if you don't have one.

how to get single row form group

I want a query which will give me desired output ,I am using following query
select table1.name1,table2.address
from table1 join table2
on(table1.key=table2.key);
it is giving me result After join nut I only need single row for each key.
Any help will be appreciated.
If any combination is allowed but only one row for each key then try this:
select table1.name1, MAX(table2.address) address
from table1
join table2
on table1.key=table2.key
group by table1.name1
try like this
select *
from (select table2.address,
rank() over ( partition by table1.name1 order by table1.key) rn
from table1 join table2 on(table1.key=table2.key))
where rn = 1

Multiple count based on dynamic criteria

I have two database for which I want to compare the amount of times a case appears.
TAB1:
ID Sequence
A2D 1
A2D 2
A2D 3
A3D 1
TAB2:
ID Sequence
A2D 1
A2D 2
A3D 1
A3D 2
Now, for this example, I am trying to get this result:
ID Table1 Table2
A2D 3 2
A3D 1 2
I have tried these code without any success:
SELECT R1.ID as ID, COUNT(R1.ID) as Table1,
COUNT(R2.ID) as Table2
FROM TAB1 AS R1, TAB2 AS R2
WHERE R1.ID = R2.ID
GROUP BY R1.ID
This one gave me wrong count values...
Also, this one simply crash:
select
(
select count(*) as Table1
from TAB1
where ID = R1.ID
),(
select count(*) as Table2
from TAB2
where ID= R1.ID
)
FROM TAB1 AS R1
As you can see though, I am trying to have my criteria dynamic. Most examples I found were including basic hard-coded criteria. But for my case, I want the query to look at my first table ID, count the amount of time it appears, do it for the 2nd table with the same ID, then move on to the next ID.
If my question lacks information or is confusing just ask me, I'll do my best to be more precise.
Thanks in advance !
Here I am using a UNION ALL as a subquery
SELECT ID, SUM(T1) AS Table1, SUM(T2) AS Table2
FROM
(SELECT ID, COUNT(ID) AS T1, 0 AS T2 FROM TAB1 GROUP BY ID
UNION ALL
SELECT ID, 0 AS T1, COUNT(ID) AS T2 FROM TAB2 GROUP BY ID)
GROUP BY ID
HAVING SUM(T1)>0 AND SUM(T2)>0
I used a different approach, but unfortunately I have to use two queries, i still don't know if they can be combined together. The first one is just for making sums of both tables, and combining the results:
SELECT "Tab1" AS [Table], Tab1.ID, Count(*) AS Total
FROM Tab1
GROUP BY "Tab1", Tab1.ID
UNION SELECT "Tab2" AS [Table], Tab2.ID, Count(*) AS Total
FROM Tab2
GROUP BY "Tab2", Tab2.ID
and, since Access supports Pivot queries, you can use this:
TRANSFORM Sum(qrySums.[Total]) AS Total
SELECT qrySums.[ID]
FROM qrySums
GROUP BY qrySums.[ID]
PIVOT qrySums.[Table];
Not sure if I understand your question, but you could try something like this:
SELECT DISTINCT t.ID,
(SELECT COUNT(ID) FROM R1 WHERE ID = t.ID) AS table1,
(SELECT COUNT(ID) FROM R2 WHERE ID = t.ID) AS table2
FROM table1 t
To get the desired results, I broke it down into two sub-queries (R1SQ and R2SQ) and a main UNION query - R1R2 that uses inner, left and right joins to include all row entries including those rows that do not appear in both tables:
R1SQ
SELECT R1.Builder, Count(R1.Builder) AS Table1
FROM R1
GROUP BY R1.Builder;
R2SQ
SELECT R2.Builder_E, Count(R2.Builder_E) AS Table2
FROM R2
GROUP BY R2.Builder_E;
R1R2
SELECT R1SQ.Builder, R1SQ.Table1, R2SQ.Table2
FROM R1SQ INNER JOIN R2SQ ON R1SQ.Builder = R2SQ.Builder_E
UNION
SELECT R1SQ.Builder, R1SQ.Table1, 0 AS Table2
FROM R1SQ LEFT JOIN R2SQ ON R1SQ.Builder = R2SQ.Builder_E
WHERE (((R2SQ.Builder_E) Is Null))
UNION
SELECT R2SQ.Builder_E, 0 AS Table1, R2SQ.Table2
FROM R1SQ RIGHT JOIN R2SQ ON R1SQ.Builder = R2SQ.Builder_E
WHERE (((R1SQ.Builder) Is Null))
ORDER BY R1SQ.Builder;

mysql - union tables by unique field

I have two tables with the same structure:
id name
1 Merry
2 Mike
and
id name
1 Mike
2 Alis
I need to union second table to first with keeping unique names, so that result is:
id name
1 Merry
2 Mike
3 Alis
Is it possible to do this with MySQL query, without using php script?
This is not a join (set multiplication), this is a union (set addition).
SELECT #r := #r + 1 AS id, name
FROM (
SELECT #r := 0
) vars,
(
SELECT name
FROM table1
UNION
SELECT name
FROM table2
) q
This will select all names from table1 and combine those with all the names from table2 which are not in table1.
(
select *
from table1
)
union
(
select *
from table2 t2
left join table1 t1 on t2.name = t1.name
where t1.id is null
)
Use:
SELECT a.id,
a.name
FROM TABLE_A a
UNION
SELECT b.id,
b.name
FROM TABLE_B b
UNION will remove duplicates.
As commented, it all depends on what your 'id' means, cause in the example, it means nothing.
SELECT DISTINCT(name) FROM t1 JOIN t2 ON something
if you only want the names
SELECT SUM(something), name FROM t1 JOIN t2 ON something GROUP BY name
if you want to do some group by
SELECT DISTINCT(name) FROM t1 JOIN t2 ON t1.id = t2.id
if the id's are the same
SELECT DISTINCT COALESCE(t1.name,t2.name) FROM
mytable t1 LEFT JOIN mytable t2 ON (t1.name=t2.name);
will get you a list of unique names from the 2 tables. If you want them to get new ids (like Alis does in your desired results), that's something else and requires the answers to a couple of questions:
do any of the names need to maintain their previous id. And if they do, which table's id should be preferred?
why do you have 2 tables with the same structure? ie what are you trying to accomplish when you generate the unique name list?