I have 3 tables like this:
Names:
ID(K) Name
--------------
1 n1
2 n2
Jobs:
ID Job
------------
1 j1
1 j2
Phones:
ID Phone
--------------
1 p1
1 p2
1 p3
1 p4
I'm doing a SELECT with LEFT OUTER JOIN:
SELECT Names.Name, Jobs.Job, Phones.Phone
FROM
Names LEFT OUTER JOIN Jobs ON Jobs.ID = Names.ID
LEFT OUTER JOIN Phones ON Phones.ID = Names.ID
and returns:
n1 j1 p1
n1 j1 p2
n1 j1 p3
n1 j1 p4
n1 j2 p1
n1 j2 p2
n1 j2 p3
n1 j2 p4
n2 null null
but i need this results:
n1 j1 p1
n1 j2 p2
n1 null p3
n1 null p4
n2 null null
what's the solution?
You're not specifying which RDBMS, but this query works on at least SQL Server, PostgreSQL and Oracle. There may be a smarter analytic function to do this, but it escapes me at the moment.
WITH pjobs AS (
SELECT id, job,
ROW_NUMBER() OVER(PARTITION BY id ORDER BY job) rn FROM jobs
), pphones AS (
SELECT id, phone,
ROW_NUMBER() OVER(PARTITION BY id ORDER BY phone) rn FROM phones
)
SELECT name, job, phone
FROM pjobs FULL JOIN pphones ON pjobs.rn = pphones.rn AND pjobs.id = pphones.id
RIGHT JOIN names ON names.id = pjobs.id OR names.id = pphones.id
An SQLfiddle to test with.
Related
I have 2 tables like this:
Table Student_Old:
id name city
1 A X
2 B Y
3 C Z
Table Student_new:
id name city
1 A X
2 M Y
3 C K
As you can see for Id 2,name is mismatching and for Id 3, city is mismatching in both tables(I am doing comparison on ID which is primary key in both table, basically student_new is backup table for old ). Now I want to get these 2 rows which are not matching.
e.g:
student_old s1, student_new s2-
s1.id s2.id s1.name s2.name s1.city s2.city
2 2 B M X X
3 3 C C Z K
Since you don't care about records which are in one table but not in the other, a simple JOIN will suffice:
SELECT s1.id AS old_id, s2.id AS new_id,
s1.name AS old_name, s2.name AS new_name,
s1.city AS old_city, s2.city AS new_city
FROM student_old s1
JOIN student_new s2
ON s1.id = s2.id
WHERE s1.name != s2.name OR s1.city != s2.city
Output:
old_id new_id old_name new_name old_city new_city
2 2 B M Y Y
3 3 C C Z K
SELECT so.id AS id_1, so.name AS name_1, so.city AS city_1,
sn.id AS id_2, sn.name AS name_2, sn.city AS city_2
FROM student_old so
INNER JOIN student_new sn
ON so.id = sn.id
WHERE so.name <> sn.name AND so.city <> sn.city
use join
select os.*,ns.* Student_Old os join Student_new ns on os.id=ns.id
where os.city!=ns.city OR os.name!=ns.name
Use inner join and where clause do filter out non matching name and city
select a.* , b.* from Student_Old inner join Student_new
on a.id=b.id
where a.name<>b.name or a.city<>b.city
I need to list supplier names of parts shipped by both S2 and S4. I have 3 tables named S, P, and SP but S and SP are the only ones I need.
SP table
sno | pno |
s1 p1
s2 p1
s2 p2
s4 p2
s4 p4
s4 p5
S table
sno | sname
S1 Smith
s2 Jones
s4 Clarke
I just have so far:
SELECT s.sname FROM s INNER JOIN sp ON s.sno = sp.sno
Can you please try this:
SELECT sname
FROM s WHERE sno IN (SELECT MAX(sno) FROM sp
GROUP BY pno HAVING COUNT(DISTINCT(sno)) > 1)
I need to list supplier names of parts shipped by both S2 and S4
Parts shipped by both s2 and s4:
select pno
from sp
where sno in ('s2','s4')
group by pno
having count(distinct sno) = 2;
Suppliers shipping these parts:
select distinct sno
from sp
where pno in
(
select pno
from sp
where sno in ('s2','s4')
group by pno
having count(distinct sno) = 2
);
Complete query for supplier names for these suppliers:
select sname
from s
where sno in
(
select sno
from sp
where pno in
(
select pno
from sp
where sno in ('s2','s4')
group by pno
having count(distinct sno) = 2
)
);
Try this one:
SELECT s.sname FROM s
INNER JOIN sp a ON a.sno = s.sno
INNER JOIN sp b ON a.sno <> b.sno AND a.pno = b.pno
WHERE a.sno IN ('s2', 's4') AND b.sno IN ('s2', 's4')
GROUP BY s.sno;
Need to get the lowest Score of each distinct Name and distinct Group. Thank you.
Data:
Group Name Score
A N1 1
B N1 5
C N1 3
A N1 4
A N2 2
A N3 6
A N1 8
B N1 7
B N2 9
Result:
A N1 1
B N1 5
C N1 3
A N2 2
A N3 6
B N2 9
select [Group], Name , min( Score)
from my_table
group by [Group], Name
Hello I have a simple table like this:
name date
n1 d1
n1 d1
n2 d1
n3 d1
n1 d2
n2 d2
n2 d2
n1 d3
n1 d3
n1 d3
n4 d3
Where n# is some name and d# is some date. I need the following result:
name date number
n1 d1 2
n2 d1 1
n3 d1 1
n1 d2 1
n2 d2 2
n1 d3 3
n4 d3 1
What I'm doing is for each date, I count the number of times n# appears. Then I display for each name and date the number.
How can I do this on SQL? thank you
It's just a simple usage of group by
select name, date, count(*)
from table1
group by name, date
Group on the name and date:
select
name, date, count(*) as number
from
SomeTable
group by
name, date
order by
name, date
So, I have two tables, Table R and Table N. The data in Table R is from Table N. My problem is I don't know the SELECT query that will display the result such as below, because there are 4 names, and SQL can only choose 1. Is there a query or any other way to get the result?
Table R:
Id1 Id2 Id3 Id4
1 3 5 7
2 4 6 8
Table N:
Id Name
1 A
2 B
3 C
4 D
5 E
6 F
7 G
8 H
After the SELECT statement, the result should look like this:
Name1 Name2 Name3 Name4
A C E G
B D F H
Anyway, thanks for helping. ^_^
SELECT
N1.Name AS `Name1`,
N2.Name AS `Name2`,
N3.Name AS `Name3`,
N4.Name AS `Name4`
FROM
R
INNER JOIN
N N1
ON
N1.Id = R.Id1
INNER JOIN
N N2
ON
N2.Id = R.Id2
INNER JOIN
N N3
ON
N3.Id = R.Id3
INNER JOIN
N N4
ON
N4.Id = R.Id4
select
n1.Name as Name1,
n2.Name as Name2,
n3.Name as Name3,
n4.Name as Name4
from
R
inner join N n1 on n1.id = R.id1
inner join N n2 on n2.id = R.id2
inner join N n3 on n3.id = R.id3
inner join N n4 on n4.id = R.id4
You can rename the table in the query
You can join the same table multiple times provided you rename it, so:
select N1.Name, N2.Name, N3.Name, N4.Name
from R
join N as N1 on N1.Id = Id1
join N as N2 on N2.Id = Id2
join N as N3 on N3.Id = Id3
join N as N4 on N4.Id = Id4
(of course that's equivalent to
select N1.Name, N2.Name, N3.Name, N4.Name
from R, N as N1, N as N2, N as N3, N as N4
where N1.Id = Id1 and
N2.Id = Id2 and
N3.Id = Id3 and
N4.Id = Id4
(the on clauses are just added to where and comma is join)