SQL Join to return data from The Same Column in the same table to two diffrent rows in result (Star Wars Example) - sql

Newbie question about joining tables. I want to retrieve a name from a column TWICE in a SQL statement, and I'm running in circles.
I Have two Tables - "Company" & "People"
Table -"People"
ID
Name
Phone
1
Luke
555-1212
2
Leia
555-1234
3
Han
999-8888
4
Anikin
888-9876
5
Obi-wan
555-1212
6
R2-D2
#% - **!?
Table - "Company"
ID
CompanyName
PrimaryContact
AltContact
1
Speeders R Us
5
1
2
Droid Repair World
6
4
3
Luke's Second Hand Store
1
4
4
Cloak World
4
5
5
Ye Old Blaster Shoppe
3
2
If I want to get a result that gives BOTH the Contact Names for a Company, How would I do it?
I can get the PrimaryContact to JOIN Properly using something like...
SELECT C.*, P.Name as 'Primary'
FROM `Company` C
Join People P on
C.PrimaryContact = P.ID
WHERE C.ID =3
which successfully returns
ID
CompanyName
PrimaryContact
AltContact
Primary
3
Luke's Second Hand Store
1
4
Luke
But for the life of me, I can't figure out how to modify this SQL to also return "Anikin" as the Alternate Contact. Is this an example of where a UNION statement would help?

You can join to the same table multiple times, just give a new alias every time.
Join People P on C.PrimaryContact = P.ID
Join People P1 on C.AltContact = P1.ID
Join People altcontact on C.AltContact = altcontact.ID
Join People P256 on C.yetanotheralternateContact = P256.ID

You need to to join for ecervy contact another Persons table
SELECT C.ID,C.CompanyName, P.Name as 'Primary' , P.Phone As 'primary_Phone', P2.Name on 'Alternative', P2.Phone as 'Alternatibe_Phone
FROM `Company` C
Join People P on
C.PrimaryContact = P.ID
Join People P2 on
C.AltContact = P2.ID
WHERE C.ID

Related

SQL Group rows in left join into one

i try create query with left join when i combine multiple rows into one. I try with GROUP_CONTENT function but when i try use it my db server is going down. I use MariaDB 10.3.17. I have tables like:
Games:
game_id game_name
1 Test
2 Stack
3 Other
data_developers:
dev_id dev_name
1 Electronic Arts
2 BioWare
3 2K Games
game_developers
developer_id game_id
1 1
2 1
2 3
Result i want:
game_id game_name devs
1 Test Electonics Arts, BioWare
2 Stack 2K Games
my two sql (but didnt work)
SELECT games.*, GROUP_CONCAT(data_developers.dev_name)
FROM games
LEFT JOIN game_developers ON game_developers.game_id = games.game_id
LEFT JOIN data_developers ON data_developers.dev_id = game_developers.dev_id
LIMIT 500
and second query
SELECT games.*
FROM games
LEFT JOIN game_developers ON game_developers.game_id = games.game_id
LEFT JOIN
(SELECT GROUP_CONCAT(data_developers.developer_name) as developers,
data_developers.developer_id FROM data_developers) x
ON x.developer_id = game_developers.developer_id
But of course, also dont work :(
Your query should be something like below-
SELECT A.game_id,B.Game_name,GROUP_CONCAT(C.dev_name)
FROM game_developers A
INNER JOIN Games B ON A.game_id = B.game_id
INNER JOIN data_developers C ON A.developer_id = C.dev_id
GROUP BY A.game_id,B.Game_name

How to find all the pairs of tuples that agree on a certain attribute

I am trying to write a query in db2 for a database that has books and the customers who bought them and I am to find the pairs of customers who bought common books.
Say for example the DB is called "DB" and it looks like this
CustomerID Book Cost
1 Harry Potter 12
2 SOUE 6
3 Harry Potter 12
4 Harry Potter 12
5 SOUE 6
6 SOUE 6
I am basically trying to get the resulting table look like
Customer1 Customer2
1 3
1 4
2 5
2 6
I have tried using group by's but I cant seem to get the idea right
I've tried
Select book
from DB
group by book
which uniquely gives me all the books but I don't know how I would go about getting the customer pairs. Any help would be greatly appreciated thank you.
I'd self-join according to the book column. In order to avoid conceptual duplicates (e.g., 1-3 and 3-1), you could make an arbitrary decision to always display the lower customer ID on the left:
SELECT DISTINCT a.customerid, b.customerid
FROM mytable a
JOIN mytable b ON a.book = b.book AND a.customerid < b.customerid
EDIT:
To answer the question in the comments, if you want to display customer names instead of ids, you'd need to join the customers table to this query, twice, once for each column:
SELECT DISTINCT ca.name AS customer1, cb.name AS customer2
FROM purchases pa
JOIN purchases pb ON pa.book = pb.book AND pa.customerid < pb.customerid
JOIN customers ca ON pa.customer_id = ca.id
JOIN customers cb ON pb.customer_id = cb.id

Get data from relational tables

I have following tables in my db.
Calls:
ID Name
1 Call1
2 Call2
3 Call3
Notes:
ID Name
1 Note 1
2 Note 2
Person:
ID Name
1 Andrew
PersonCalls:
ID CallID PersonID
1 1 1
2 2 1
PersonNotes:
ID NoteID PersonID
1 1 1
1 2 1
Now I need to get data from these tables according to person id. I am able to get data from 2 tables, for example Notes and PersonNotes, but I am not able to get combined data from these tables. This should be the result.
Result:
PersonID Note Call
1 Note1 Call1
1 Note2 Call2
Please suggest
Thanks
Use Join (ie: Inner Join):
select distinct p.ID as PersonID, n.Name as Note, c.Name as Call from Person p
inner join PersonCalls pc on p.ID = pc.PersonID
inner join PersonNotes pn on p.ID = pn.PersonID
inner join Calls c on pc.CallID = c.ID
inner join Notes n on pn.NoteID = n.ID
Without getting too detailed you can use a left join on dbo.calls.ID, dbo.notes.id, dbo.person.id, etc if you are using MS SQL server. Otherwise are you sure you can't just write a report?

Efficient way for finding attributes in a table which belong together, based on second table

I have two tables:
person
----------
id name
1 peter
2 paul
3 mary
4 george
5 andy
and
living
-------
id key
1 1
2 1
3 2
4 2
5 2
What would be the most efficient query for finding all ids in person which belong together, if I know the name. Let's say I want to find out: "Who is Mary living with"? In person, Mary's id is 3. I check living for the key, which belongs to Mary, which is 2. Now I can retrieve all ids in living which go with key 2, and I have the ids which live together with Mary.
This is what I got so far:
SELECT p2.name
FROM person p1
JOIN living l1
ON p1.id = l1.id
JOIN living l2
ON l1.key = l2.key
JOIN person p2
ON l2.id = p2.id
WHERE p1.name = 'mary'
Is there a better way? The result seems to be fine, but it doesn't feel right to perform three JOINS.
What you could do in you case is:
DEFINE name CHAR(15);
LET name = 'mary'
define keyValue char(10);
select l.key into keyValue from person p left outer join living l on p.id= l.id and p.name= name
select p.*, l.* from person p left outer join living l on p.id=l.id
where key= keyValue
I have never used Informix before, however the the best solution should be along those lines or at least close to them.
Thanks

What Join should I use in SQL

I have four tables in my Database:
Person that contains ID(PK) and Name.
Person_Skill that contains ID(PK), PID(FK), Skill(FK) and SkillLevel(FK).
Skill that contains ID(PK) and SkillLabel.
SkillLevel that contains ID(PK) and Name.
Every skill has level from 0 to 7
Now I want to display all the skill that the person has(Include the skilllevel = 0)
Select
[dbo].Person.Name as Name,
[Skill].SkillLabel as SkillName,
[Person_Skill].[SkillLevel] as SkillLevel
From
([dbo].Person inner join [dbo].[Person_Skill] ON [dbo].[Person_Skill].PID= Person.ID)
inner join [dbo].[Skill] ON [dbo].[Person_Skill].Skill=Skill.ID
The above code only display the skill that person has from level 1 to level 7.
I believe the reason I only get the skill from level 1 to 7 is because the person table only contains the skill from level 1 to 7, but I'm not sure about this. I got the database from other. If my assumption is correct, is there anyway to do this? To get all the skills in the skill table and display the skill level that the person has(Include skillllevel =0).
Sample Data:
Person
ID Name
----------
1 Michael
2 Alex
Person_Skill
ID PID SkillID Skill_Level
5 1 10 5
6 2 11 1
7 1 12 7
8 1 13 5
Skill
ID Name
10 java
11 C++
12 HTML
13 ASP
14 C
15 .NET
16 C#
17 Objective
The expect results are;
Name SkillName SkillLevel
----------------------------
Alex java 0
Alex C++ 1
Alex HTML 0
Alex ASP 0
Alex C 0
Alex .NET 0
Alex C# 0
Alex Objective C 0
Michael java 5
Michael C++ 0
Michael HTML 7
Michael ASP 0
Michael C 0
Michael .NET 5
Michael C# 0
Michael Objective C0
The current query only output
Alex C++ 1
Michael java 5
Michael HTML 7
Michael .NET 5
Edit, if you want to return all skill names for each person, then you will want to use:
select d.p_name,
d.s_name SkillName,
coalesce(ps.Skill_Level, 0) Skill_Level
from
(
select p.id p_id, p.name p_name, s.id s_id, s.name s_name
from person p
cross join skill s
) d
left join person_skill ps
on d.p_id = ps.pid
and d.s_id = ps.skillid
left join skill s
on ps.skillid = s.id
See SQL Fiddle with Demo
If you want to include all Skills 0-7, then you will want to use a LEFT JOIN. You query will be similar to the following:
select p.Name as Name,
s.SkillLabel as SkillName,
ps.[SkillLevel] as SkillLevel
from [dbo].[Skill] s
left join [dbo].[Person_Skill] ps
on ps.Skill=s.ID
left join [dbo].Person p
on ps.PID = p.ID
Edit, without seeing any data it is difficult to determine. But if you want to retrieve all SkillLevels, then you will need to include that table. You might need to use:
select
p.Name as Name,
s.SkillLabel as SkillName,
sl.[Name] as SkillLevel
from SkillLevel sl
left join [dbo].[Person_Skill] ps
on ps.SkillLevel=sl.ID
left join [dbo].[Skill] s
on ps.Skill = s.Id
left join [dbo].Person p
on ps.PID = p.ID
You would want to use a LEFT JOIN which when tableA is inner joined on tableb would return all records from tableA regardless of whether or not there was a match from tableB
Therefore, if there are no persons with a skill of 0, you will still get back all of the person records.
An INNER JOIN will only return rows where there is a match on both sides. So in your code if a person does not have a skill with level 0 it would not be returned.
You could do a LEFT or RIGHT join and these get all the rows from the table on either the left or the right side. I think you probably want to use a left join, but without knowing more about your schema it's hard to say for sure. See the answer given to the question Left join and Left outer join in SQL Server for more detail on the differences in different join types