Using a table to lookup multiple IDs on one row - sql

I have two tables I am using at work to help me gain experience in writing SQL queries. One table contains a list of Applications and has three columns -
Application_Name, Application_Contact_ID and Business_Contact_ID. I then have a separate table called Contacts with two columns - Contact_ID and Contact_Name. I am trying to write a query that will list the Application_Name and Contact_Name for both the Applications_Contact_ID and Business_Contact_ID columns instead of the ID number itself.
I understand I need to JOIN the two tables but I haven't quite figured out how to formulate the correct statement. Help Please!
APPLICATIONS TABLE:
+------------------+------------------------+---------------------+
| Application_Name | Application_Contact_ID | Business_Contact_ID |
+------------------+------------------------+---------------------+
| Adobe | 23 | 23 |
| Word | 52 | 14 |
| NotePad++ | 44 | 989 |
+------------------+------------------------+---------------------+
CONTACTS TABLE:
+------------+--------------+
| Contact_ID | Contact_Name |
+------------+--------------+
| 23 | Tim |
| 52 | John |
| 14 | Jen |
| 44 | Carl |
| 989 | Sam |
+------------+--------------+
What I am trying to get is:
+------------------+--------------------------+-----------------------+
| Application_Name | Application_Contact_Name | Business_Contact_Name |
+------------------+--------------------------+-----------------------+
| Adobe | Tim | Tim |
| Word | John | Jen |
| NotePad++ | Carl | Sam |
+------------------+--------------------------+-----------------------+
I've tried the below but it is only returning the name for one of the columns:
SELECT Application_Name, Application_Contact_ID, Business_Contact_ID, Contact_Name
FROM Applications
JOIN Contact ON Contact_ID = Application_Contact_ID

This is a pretty critical and 101 part of SQL. Consider reading this other answer on a different question, which explains the joins in more depth. The trick to your query, is that you have to join the CONTACTS table twice, which is a bit hard to visualize, because you have to go there for both the application_contact_id and business_contact_id.
There are many flavors of joins (INNER, LEFT, RIGHT, etc.), which you'll want to familiarize yourself with for the future reference. Consider reading this article at the very least: https://www.techonthenet.com/sql_server/joins.php.
SELECT t1.application_name Application_Name,
t2.contact_name Application_Contact_name,
t3.contact_name Business_Contact_name
FROM applications t1
INNER JOIN contacts ON t2 t1.Application_Contact_ID = t2.contact_id -- join contacts for appName
INNER JOIN contacts ON t3 t1.business_Contact_ID = t3.contact_id; -- join contacts for busName

Related

SQL - specific requirement to compare tables

I'm trying to merge 2 queries into 1 (cuts the number of daily queries in half): I have 2 tables, I want to do a query against 1 table, then the same query against the other table that has the same list just less entries.
Basically its a list of (let's call it for obfuscation) people and hobby. One table is ALL people & hobby, the other shorter list is people & hobby that I've met. Table 2 would all be found in table 1. Table 1 includes entries (people I have yet to meet) not found in table 2
The tables are synced up from elsewhere, what I'm looking to do is print a list of ALL people in the first column then print the hobby ONLY of people that are on both lists. That way I can see the lists merged, and track the rate at which the gap between both lists is closing. I have tried a number of SQL combinations but they either filter out the first table and match only items that are true for both (i.e. just giving me table 2) or just adding table 2 to table 1.
Example of what I'm trying to do below:
+---------+----------+--+----------+---------+--+---------+----------+
| table1 | | | table2 | | | query | |
+---------+----------+--+----------+---------+--+---------+----------+
| name | hobby | | activity | person | | name | hobby |
| bob | fishing | | fishing | bob | | bob | fishing |
| bill | vidgames | | hiking | sarah | | bill | |
| sarah | hiking | | planking | sabrina | | sarah | hiking |
| mike | cooking | | | | | mike | |
| sabrina | planking | | | | | sabrina | planking |
+---------+----------+--+----------+---------+--+---------+----------+
Normally I'd just take the few days to learn SQL a bit better however I'm stretched pretty thin at work as it is!
I should mention the table 2 is flipped and the headings are all unique (don't think this matters)!
I think you just want a left join:
select t1.name, t2.activity as hobby
from table1 t1 left join
table2 t2
on t1.name = t2.person;

How to create a table from different query results SQL

I want to create a new table using the results from some queries. I might be looking at this the wrong way so please feel free to let me know. Because of this I will try to make this question simple without putting my code to match each employee number with each manager level column from table2
I have two tables, one has employee names and employee numbers example
table 1
+-------------+-----------+-------------+-------------+
| emplpyeenum | firstname | last name | location |
+-------------+-----------+-------------+-------------+
| 11 | joe | free | JE |
| 22 | jill | yoyo | XX |
| 33 | yoda | null | 9U |
+-------------+-----------+-------------+-------------+
and another table with employee numbers under each manager level so basically a hierarchy example
Table 2
+---------+----------+----------+
| manager | manager2 | manager3 |
+---------+----------+----------+
| 11 | 22 | 33 |
+---------+----------+----------+
I want to make a new table that will have the names besides the numbers, so for example but with employee number beside the names
+---------+--------+----------+
| level 1 | level2 | level3 |
+---------+--------+----------+
| jill | joe | yoda |
+---------+--------+----------+
How can I do this?
edit sorry guys I don't have permission to create a new table or view
Why not change your table2 to this?
+------------+----------+
| EmployeeId | ManagerId|
+------------+----------+
| 11 | NULL |
+------------+----------+
| 22 | 11 |
+------------+----------+
| 33 | 22 |
+------------+----------+
Then you can do what you want with the data. At least your data will be properly normalized. In your table2. What happen if employee 33 hire another employee below him? You will add another column?
Based on your available table, this should give you the result you want.
SELECT m1.firstname, m2.firstname, m3.firstname
FROM table2 t
LEFT JOIN table1 m1 ON m1.employeenum = t.manager
LEFT JOIN table1 m2 ON m2.employeenum = t.manager2
LEFT JOIN table1 m3 ON m3.employeenum = t.manager3
You can just do a basic create table, then do a insert select to that will fill the table the way you need it. All you have to do is replace the select statement that I provided with the one you used to create the levels table output.
create table Levels
(
level1 varchar(25),
level2 varchar(25),
level3 varchar(25)
)
insert into Levels(level1, level2, level3)
select * from tables --here you would put the select statement that you used to create the information. If you dont have this script then let me know

Sql data from row to column with reference to another column

Parent table
+====+===========+
| id | firstname |
+====+===========+
| 1 | abc |
+----+-----------+
| 2 | bcd |
+----+-----------+
| 3 | cde |
+----+-----------+
StudentRelationship table
+==========+==========+===========+
| relation | parentid | studentid |
+==========+==========+===========+
| father | 1 | s0001 |
+----------+----------+-----------+
| mother | 2 | s0001 |
+----------+----------+-----------+
| father | 3 | s0002 |
+----------+----------+-----------+
STUDENT table
+=======+===========+==========+=========+======+
| id | firstname | lastname | address | sex |
+=======+===========+==========+=========+======+
| s0001 | shdj | khb | jxx | male |
+-------+-----------+----------+---------+------+
It would be great if you could help me create a query which will return studentid ,name,father name,mother name,sex,address.
Based on what you've posted, then updated in your comments, I think this should work for you. I am sure someone with more advanced SQL skills can post a more elegant way to do this. But this is what I came up with:
SELECT DISTINCT cte.studentid
,studentFirstName
,studentLastName
,father.fatherFirstName
,mother.motherFirstName
,sex
,address
FROM cte
LEFT JOIN father ON cte.studentid = father.studentid
LEFT JOIN mother ON cte.studentid = mother.studentid
The following is an example where a student (Jeff Jones) has two fathers (let's say one of them is the step-father):
A few recommendations here:
Take a course on SQL syntax fundamentals (any type MySQL, T-SQL, etc..)
Read about FROM and JOIN
When posting your question here, the table examples should have better test data. "asdfkj", "shdsf", "Asdjkfdjkf" are horribly hard to
use to test code against because there is no context of what you are
looking at. I realize you are just posting an example, and the context
of the rows is partly insignificant, but it just makes for easier
question answering, and doesn't scare off people who would want to
answer your question.
Here is an DEMO you can play with, that has reasonable data in the fields you've mentioned.

Using Join, select values from multiple SQL tables without a foreign key

I have a database containing two tables Team and User.
Every team can have one or two users in it.
I wish to select an output of the table Team such that information of the both the users from the table User are included.
It'll be easier to understand once I define the table structures.
Table Team:
+-----------+-------------------+-------------------+-----------------+
| team_name | user_one | user_two | team_note |
+-----------+-------------------+-------------------+-----------------+
| Team one | skuhsa#jdds.dfd | kgihse#kdhf.dfj | one to twenty |
| Team two | dsjgknsz#djfd.fkg | | three to thirty |
+-----------+-------------------+-------------------+-----------------+
Table User:
+-------------------+-----------+-----------------+
| email | user_name | user_note |
+-------------------+-----------+-----------------+
| skuhsa#jdds.dfd | skuhsaone | gimme money |
| kgihse#kdhf.dfj | kgihse | drop it |
| dsjgknsz#djfd.fkg | dsjgknsz | just eat it |
+-------------------+-----------+-----------------+
The output I'm looking for goes like this.
+-----------+--------------------+-----------+------------------+-----------+-----------------+
| team_name | user_one | user_name | user_two | user_name | team_note |
+-----------+--------------------+-----------+------------------+-----------+-----------------+
| Team one | skuhsa#jdds.dfd | skuhsaone | kgihse#kdhf.dfj | kgihse | one to twenty |
+-----------+--------------------+-----------+------------------+-----------+-----------------+
| Team two | dsjgknsz#djfd.fkg | dsjgknsz | | | three to thirty |
+-----------+--------------------+-----------+------------------+-----------+-----------------+
I have a good feeling that it can be done easily, but right now I'm trying all sorts of JOINs and stuff and ending up with duplicate results or rows.
If there is any PostgreSQL specific ways to do it, it'd just fine with me.
SELECT * FROM Team LEFT JOIN User ON Team.user_one=User.email works, but how do I select only the columns I want? i.e., how will it differentiate b/w columns for the first and the second user?
A couple of left joins should do the trick:
SELECT team_name, user_one, u1.user_name, user_two, u2.user_name, team_note
FROM team t
LEFT JOIN user u1 ON t.user_one = u1.email
LEFT JOIN user u2 ON t.user_one = u2.email
The answer is actually quite simple, as the comment says simply use a LEFT join, this could by saying LEFT JOIN [TableName]
SELECT * FROM [Team]
LEFT JOIN [User]
Also take a look at
http://www.w3schools.com/sql/sql_join_left.asp
Edit:
Your second option would be to do this:
SELECT * FROM [Team]
UNION
SELECT * FROM [User]
An inner join or a left join can be used to extract data from both tables.
But the result of the query will be more similar to the following:
+-----------+--------------------+-----------+-----------------+
| team_name | user_one | user_name | team_note |
+-----------+--------------------+-----------+-----------------+
| Team one | skuhsa#jdds.dfd | skuhsa | one to twenty |
+-----------+--------------------+-----------+-----------------+
| Team one | skuhsa#jdds.dfd | kgihse | one to twenty |
+-----------+--------------------+-----------+-----------------+
| Team two | dsjgknsz#djfd.fkg | dsjgknsz | three to thirty |
+-----------+--------------------+-----------+-----------------+
This is the best solution because you don't know how many users are present in a team what happens if they are 3 (or 100?) ? But it is different from your expectations so check if you agree with that form.
firstly you sould re-think aout tables. What is the meaning wirting user e-mails in two different tables? In the end you will get all of them in one table.
Other than that you shoul look at foreign key. Foreign keys link tables together. I think your tables must be like.
+-----------+-------------------+-------------------+-
| team_name | team_note | team_id(Primary key)
+-----------+-------------------+-------------------+
| Team one | one to twenty | 1
| Team two | stuff | 2
+-----------+-------------------+-------------------+
+-------------------+-----------+-----------------+-------------------------------------------------
| email | user_name | user_note | f_team_id(foreign_key) to team.team_id
+-------------------+-----------+-----------------+--------------------------------------
| skuhsa#jdds.dfd | skuhsaone | gimme money | 1
| kgihse#kdhf.dfj | kgihse | drop it | 1
| dsjgknsz#djfd.fkg | dsjgknsz | just eat it | 2
+-------------------+-----------+-----------------+------------------------------------------
After that
SELECT * FROM team JOIN user ON user.f_team_id=team.team_id; OR
SELECT * FROM team, user WHERE user.f_team_id=team.team_id;

SQL: Joining two tables with email adresses in SQL Server [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have spent hours researching how to write the proper SQL for the following task, and finally I feel that I have to get some help as this is the most complex SQL query I have ever had to write :(
I am putting together an email list with all the email adresses that we have on our customers.
I have two tables: one customer table that contains customer level information, and one contact person table that contains person level information. Most of the data is overlapping, so the same email adress will occure in both tables. But the email adress field can be empty in both tables, and I do not want to return any empty rows.
Users that buy in our physical store are often only registered in the customer level table, but users that buys online are always registered both in the customer level table and the person level table.
I want to create a full list where I get all email adresses, where all email adresses are unique, no email adresses are duplicates and no email adresses are null.
Also I want to join in columns from the customer table when the data is retrieved from the person table (the zip code in my example below).
Customers
| CustomerID | Firstname | Lastname | Email | Zipcode |
| 22 | Jeff | Carson | jeffcar#mail.com | 81712 |
| 29 | John | Doe | null | 51211 |
| 37 | Gina | Andersen | null | 21147 |
| 42 | Brad | Cole | brad#company.org | 39261 |
Contact persons
| PersonID | CustomerID | Firstname | Lastname | Email |
| 8712 | 22 | Jeff | Carson | null || 8916 | 29 | Jane | Doe | jane#doe.net || 8922 | 29 | Danny | Doe | null |
| 9181 | 37 | Gina | Andersen | gina#gmail.com |
| 9515 | 37 | Ben | Andersen | ben88#gmail.com |
I want to join the tables to generate the following:
Final table
| PersonID | CustomerID | Firstname | Lastname | Email | Zipcode |
| 8712 | 22 | Jeff | Carson | jeffcar#mail.com | 81712 |
| 8916 | 29 | Jane | Doe | jane#doe.net | 51211 |
| 9181 | 37 | Gina | Andersen | gina#gmail.com | 21147 |
| 9515 | 37 | Ben | Andersen | ben88#gmail.com | 21147 |
| null | 42 | Brad | Cole | brad#company.org | 39261 |
I guessed this would be a fairly common task to do, but I haven't found anyone with a similar question, so I put my trust in the expertise out there.
This SQL will get you exactly the results table you were looking for. I've made a live demo you can play with here at SQLFiddle.
SELECT
ContactPerson.PersonID,
Customer.CustomerID,
COALESCE(ContactPerson.FirstName, Customer.FirstName) AS FirstName,
COALESCE(ContactPerson.LastName, Customer.LastName) AS LastName,
COALESCE(ContactPerson.Email, Customer.Email) AS Email,
Customer.ZipCode
FROM Customer
LEFT JOIN ContactPerson
ON ContactPerson.CustomerID = Customer.CustomerID
WHERE COALESCE(ContactPerson.Email, Customer.Email) IS NOT NULL
Results (identical to your desired results):
| PersonID | CustomerID | FirstName | LastName | Email | ZipCode |
| 8712 | 22 | Jeff | Carson | jeffcar#mail.com | 81712 |
| 8916 | 29 | Jane | Doe | jane#doe.net | 51211 |
| 9181 | 37 | Gina | Andersen | gina#gmail.com | 21147 |
| 9515 | 37 | Ben | Andersen | ben88#gmail.com | 21147 |
| NULL | 42 | Brad | Cole | brad#company.org | 39261 |
A quick explanation of some key points to aid understanding:
The query uses a LEFT JOIN to join the two tables together. JOINs are pretty common once you get into SQL problems like this. I won't go into an in-depth explanation here: now that you know what they are called you should have no trouble Googling for loads of info on them!
NB: COALESCE basically means 'the first one of these options which isn't null' (docs). So this query will grab their name and email address from ContactPerson IF POSSIBLE, otherwise from Customer. If NEITHER of these tables hold an email address, then the WHERE clause makes sure that record isn't included at all, as required.
This will work:
SELECT b.PersonID
,a.CustomerID
,a.FirstName
,a.LastName
,COALESCE(a.Email,b.Email) AS Email
,a.ZipCode
FROM Customers a
LEFT JOIN Contact b
ON a.CustomerID = b.CustomerID
WHERE COALESCE(a.Email, b.Email) IS NOT NULL
Demo: SQL Fiddle
select con.personid,
con.customerid,
con.firstname,
con.lastname,
coalesce(con.email, cus.email) email,
cus.zipcode
from contact_persons con
right join
customers cus
on con.customerid = cus.customerid