use data from multiple tables in SQL - mysql

need some quick help.. i think i'm supposed to use INNER JOIN, but i'm not really sure.
List the employee ID and the full name of the employee who sold or packaged the
transactions placed by customer Benjamin Jones. Each employee should only show up
once in your results
employeeID, first and last are in the EMPLOYEES table
benjamin jones' memberID is 101 and in the MEMBERS table
memberID and transactionID and soldorpackagedby are in the TRANSACTIONS table
this is what I have to start it off but don't know how to finish it.
SELECT EmployeeID, First, Last
FROM Employees
WHERE MemberID = '101'
thanks!

Try -
SELECT employees.EmployeeID,
employees.First,
employees.Last
FROM employees
JOIN transactions ON employees.EmployeeID = transactions.SoldOrPackagedBy
WHERE transactions.memberID = 101
GROUP BY employees.EmployeeID;
Because you are using data from more than one table in this SQL statement you will need to specify which table a repeated field name such as EmployeeID will come from, hence employees.EmployeeID. employee. is probably not called for in front of First and Last but I tend to put it in anyway since the habit can help avoid bugs occurring when I am writing more complex statements.
JOIN without INNER, LEFT, RIGHT or FULL in front is the same as INNER JOIN (see https://www.w3schools.com/sql/sql_join.asp).
Since the Member's ID is already known and used in the Transactions table, and we are not being asked to refer to any other detail about the member here, then there is no need to link in the Members table.
Without GROUP BY the SELECT statement will return a record for every time an Employee packaged a Transaction for a Member. These details would be the same every time. Using GROUP BY would reduce this to just one instance of those details.
If you have any questions or comments, then please feel free to post a Comment accordingly.

Try this one
SELECT employees.EmployeeID,
employees.First,
employees.Last
FROM employees
JOIN transactions ON employees.EmployeeID = transactions.EmployeeID
WHERE transactions.memberID = 101
GROUP BY employees.EmployeeID, employees.First, employees.Last ;

Related

JOIN data from bridging table

I'm taking a database class and I'm having troubles with using the JOIN command to get the data I need. I hope I'm on the right track...I would appreciate any inputs if there is a better way both in my model and query.
Sales transaction that each employee has processed
, I'm trying to answer the following question:
Here is a query I tried but fail to come up with correct output. I had to use a table alias for sales because I kept getting unique errors. I only have 10 rows in my bridging table however, I got 100 results back...JOIN statements are kicking my butt right now.
SELECT sales.cashier, inventory.prod_name, inventory.unit_price
FROM inventory, sales
JOIN inv_sales ON inventory_prod_id = inventory.prod_id
JOIN sales AS sales1 ON sales_sales_id = sales_id;
edit: Additional requested data
Here is a screenshot of some sample data.
I had to put them all on one pic due to site restrictions.
Tables:
Top, Inv_sales
Middle, Sales
Bottom, Inventory
Expected output:
cashier > product name > unit price
You might try something like this:
SELECT s.cashier, i2.prod_name, i2.unit_price
FROM sales s
JOIN inv_sales i1
ON i1.sales_sales_id = s.sales_id
JOIN inventory i2
ON i1.inventory_prod_id = i2.prod_id
ORDER BY s.cashier,s.date;
It uses a unique alias for each table, and uses the modern form of joining tables. Also, since the requirement was to get the sales for each employee, I added an order by so an employees sales would be grouped together.

Join error and order by

I'm trying to write a query which does the below:
For every guest who has the word “Edinburgh” in their address show the total number of nights booked. Be sure to include 0 for those guests who have never had a booking. Show last name, first name, address and number of nights. Order by last name then first name.
I am having problems with making the join work properly,
ER Diagram Snippet:
Here is my current (broken) solution:
SELECT last_name, first_name, address, nights
FROM booking
RIGHT JOIN guest ON (booking.booking_id = guest.id)
WHERE address LIKE '%Edinburgh%';
Here is the results from that query:
The query is partially complete, hoping someone can help me out and create a working version. I'm currently in the process of learning SQL so apologies if its a rather basic or dumb question!
Your query seems almost correct. You were joining the booking id with guets id which gave you some results because of overlapping (matching) ids, but this most likely doesn't correspond to the foreign keys. You should join on guest_id from booking to id from guest.
I'd add grouping to sum all booked nights for a particular guest (assuming that nights is an integer):
SELECT g.last_name, g.first_name, g.address, SUM(b.nights) AS nights
FROM guest AS g
LEFT JOIN booking AS b ON b.guest_id = g.id
WHERE g.address LIKE '%Edinburgh%'
GROUP BY g.last_name, g.first_name, g.address;
Are you sure that nights spent should be calculated using nights field? Why can it be null? If you'd like to show zero for null values just wrap it up with a coalesce function like that:
COALESCE(SUM(b.nights), 0)
Notes:
Rewriten RIGHT JOIN into LEFT JOIN, but that doesn't affect results - it's just cleaner for me
Using aliases eg. AS g makes the code shorter when specifying joining columns
Reference every column with their table alias to avoid ambiguity
SELECT g.first_name,
g.last_name,
g.address,
COALESCE(Sum(b.nights), 0)
FROM booking b
RIGHT JOIN guest g
ON ( b.guest_id = g.id )
WHERE address LIKE 'edinburgh%'
GROUP BY g.last_name,
g.first_name,
g.address;
This post answers your questions about how to make the query.
MySQL SUM with same ID
You can simply use COALESCE as referenced here to avoid the NULL Values
How do I get SUM function in MySQL to return '0' if no values are found?

mysql multiple joins query not returning desired ouput

I have three tables customers, orders, payments
I am trying to get the record with inner join of a customer with his different orders and payment methods he use against the orders.
For example
customer_name Order_status Payment_method
David shipped CASH
David cancelled CHEQUE
When I run the query it repeats the record three times and result also not as I mention above in example.
Here is query.
SELECT cust_name
, order_status
, pay_method
FROM customer
INNER JOIN order_tbl ON customer.cust_id = order_tbl.cust_id
INNER JOIN payments ON payments.cust_id = order_tbl.cust_id
Is my query alright or do I need to mention my db structure as well?
You are missing a relationship there. Your orders and payments need to link together somehow, i'm assuming there should be an order_id column in both tables ?
SELECT cust_name
, order_status
, pay_method
FROM customer
INNER JOIN order_tbl
ON customer.cust_id = order_tbl.cust_id
INNER JOIN payments
ON payments.cust_id = order_tbl.cust_id
AND payments.order_id = orders_tbl.order_id --<<--- this line here is missing
If you dont have that kind of link, how do you logically link a payment to an order - because that will be your link that you're missing.
You are getting duplicate records because the criteria is matched, nothing wrong with MySQL, it's returning results based on what you asked. Have you checked the ID's of the duplicate records to make sure that they are different? It may be the same record with different payment ID, so it will definitely return the customer and order records that are related for each record that a relationship exists. You could use DISTINCT(THE_FIELD) if you want to make the query distinct based on some criteria.
I am answering with limited knowledge on your project based on the information you provided. As mentioned in the comment above, more information would get an even better answer.
You must probably missed using the primary key of order_tbl to join the third table.

Remove duplicates from LEFT JOIN query

I am using the following JOIN statement:
SELECT *
FROM students2014
JOIN notes2014 ON (students2014.Student = notes2014.NoteStudent)
WHERE students2014.Consultant='$Consultant'
ORDER BY students2014.LastName
to retrieve a list of students (students2014) and corresponding notes for each student stored in (notes2014).
Each student has multiple notes within the notes2014 table and each note has an ID that corresponds with each student's unique ID. The above statement is returning a the list of students but duplicating every student that has more than one note. I only want to display the latest note for each student (which is determined by the highest note ID).
Is this possible?
You need another join based on the MAX noteId you got from your select.
Something like this should do it (not tested; next time I'd recommed you to paste a link to http://sqlfiddle.com/ with your table structure and some sample data.
SELECT *
FROM students s
LEFT JOIN (
SELECT MAX(NoteId) max_id, NoteStudent
FROM notes
GROUP BY NoteStudent
) aux ON aux.NoteStudent = s.Student
LEFT JOIN notes n2 ON aux.max_id = n2.NoteId
If I may say so, the fact that a table is called students2014 is a big code smell. You'd be much better off with a students table and a year field, for many reasons (just a couple: you won't need to change your DB structure every year, querying across years is much, much easier, etc, etc). Perhaps you "inherited" this, but I thought I'd mention it.
GROUP the query by studentId and select the MAX of the noteId
Try :
SELECT
students2014.Student,
IFNULL(MAX(NoteId),0)
FROM students2014
LEFT JOIN notes2014 ON (students2014.Student = notes2014.NoteStudent)
WHERE students2014.Consultant='$Consultant'
GROUP BY students2014.Student
ORDER BY students2014.LastName

Getting object if count is less then a number

I have 2 simple tables - Firm and Groups. I also have a table FirmGroupsLink for making connections between them (connection is one to many).
Table Firm has attributes - FirmID, FirmName, City
Table Groups has attributes - GroupID, GroupName
Table FirmGroupsLink has attributes - FrmID, GrpID
Now I want to make a query, which will return all those firms, that have less groups then #num, so I write
SELECT FirmID, FirmName, City
FROM (Firm INNER JOIN FirmGroupsLink ON Firm.FirmID =
FirmGroupsLink.FrmID)
HAVING COUNT(FrmID)<#num
But it doesn't run, I try this in Microsoft Access, but it eventually should work for Sybase. Please show me, what I'm doing wrong.
Thank you in advance.
In order to count properly, you need to provide by which group you are couting.
The having clause, and moreover the count can't work if you are not grouping.
Here you are counting by Firm. In fact, because you need to retrieve information about the Firm, you are grouping by FirmId, FirmName and City, so the query should look like this:
SELECT Firm.FirmID, Firm.FirmName, Firm.City
FROM Firm
LEFT OUTER JOIN FirmGroupsLink
ON Firm.FirmID = FirmGroupsLink.FrmID
GROUP BY Firm.FirmID, Firm.FirmName, Firm.City
HAVING COUNT(FrmID) < #num
Note that I replace the INNER JOIN by a LEFT OUTER JOIN, because you might want Firm which doesn't belongs to any groups too.