JOIN data from bridging table - mysql

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.

Related

use data from multiple tables in SQL

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 ;

Multitable counting and multiplying in same query

I have got a somewhat complicated problem. This is my situation (ERD).
For a dashboard i need to create a pivot table that shows me the total amount of competences used by the vacancies. Therefore I need to:
Count the amount of vacancies per template
Count the amount of templates per competence
and last: multiply these numbers to get the total amount of comps used.
I have the first query:
SELECT vacancytemplate_id, count(id)
FROM vacancies
group by vacancytemplate_id;
And the second query isn't that difficult either, but I don't know what the right solution will be. I'm literally brainstuck. My mind can't comprehend how I can achieve the next step and put it down in a query. Please kind stranger, help me out :)
EDIT: my desired result is something like this
NameOfComp, NrOfTimesUsed
Leading, 17
Inspiring, 2
EDIT2: the meta query it should look like:
SELECT NameOfComp, (count of the competences used by templates) * (number of vacancies per template)
EDIT3: http://sqlfiddle.com/#!9/2773ca SQLFiddle
Thanks a lot!
If I am understanding your request correctly, you are wanting a count of competences per vacancy. This can be done very simply due to your table structure:
Select v.ID, count(*) from vacancy as v inner join CompTemplate_Table as CT
on v.Template_ID = CT.Template_ID group by v.ID;
The reason you can do only one join is because there will be a record in the CompTemplate_Table for every competency in each template. Additionally, the same key is used to join vacancy to templates as is used to join templates to CompTemplate_Table, so they represent the same key value (and you can skip joining the Templates table if you don't need data from there).
If you are wanting to add this data to a pivot table, I will leave that exercise to you. There are a number of tutorials available if you do a quick google search and it should not be that hard.
UPDATE: For the second query you are looking at something like:
Select cp.NameOfComp, count(*) from vacancy as v inner join CompTemplate_Table as CT
on v.Template_ID = CT.Template_ID inner join competencies as CP
on CP.ID = CT.Comp_ID
group by CP.NameOfComp
The differences here are you are adding in the comptetencies table, as you need data from that, and grouping by the CP.NameOfComp instead of the vacancy id. You can also restrict this to specific templates, competencies, or vacancies by adding in search conditions (e.g. where CP.ID = 12345)

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

How do I get MYSQL to join a whole table?

I have a SELECT query that returns the response based on an unique ID, so I always get just one row.
I thought that I could save my machine an extra SELECT query if I simply added the prices table to the result, and read them to memory later on.
Would that be a good approach or am I missing something ?
(I tried it out and seems to get the job done)
SELECT *
FROM subscriptions
LEFT JOIN prices ON 1=1
WHERE subscriptions.ID = 100
edit: The prices table has no ID. I just need to get the complete table, I used to have a different SELECT just for that
This looks like a terrible idea... you should join the subscriptions table to the prices table using the foreign key that you (supposedly/should) have.
Assuming your prices table has a subscription ID column then your query should look something like this:
SELECT *
FROM subscriptions LEFT JOIN prices ON subscriptions.ID=prices.ID
WHERE subscriptions.ID=100
What this will do is produce a cartesian join - not too bad since you're limiting the 'subscriptions' side of things to a single record, but will still produce as many rows as there's records in the price side. Where this gets bad is when you've got multiple rows on both sides. Then you get n x m results - think of how big the result set would be if you had 50,000 subscriptions joined against 1000 prices: 50,000 x 1,000 = 50 million result rows.
First off, this approach is going to be much less clear what you're doing than two SELECT statements unless there is an actual relation between the tables. Second, it's probably going to be slower, because you're transferring much more data (each row of prices additionally gets all the fields from subscriptions copied).
If subscriptions and prices are related, you want to change that ON condition to use the relation, so you're only pulling the data you need.
SELECT *
FROM subscriptions s LEFT JOIN prices p ON (s.subscription_id = p.subscription_id)
WHERE s.subscription_id = 100
One thing you definitely don't want to do is this:
SELECT *
FROM subscriptions s LEFT JOIN prices p ON (1=1)
as that'd pull the full Cartesian product. Once your tables get sufficiently large, that will run you out of temporary table space.
why your condition have 1=1 ?
I thing that is's must something like this:
SELECT s.*,p.*
FROM subscriptions as s
LEFT JOIN prices as p ON p.product_id=s.product_id
WHERE s.ID = 100
show me your full fields of tables subscriptions and prices to help for you
This?
SELECT *
FROM subscriptions, prices
WHERE subscriptions.ID = 100
You'll get horrible results like this, but it seems this is what you wanted.
The table with less rows will have its rows repeating. Again, this is not a good practice.
Use two SELECTs.
This is a cross join http://en.wikipedia.org/wiki/Join_(SQL)#Cross_join
which means your resultset will contain as many rows as you have in the prices table.
So I guess it is not a good idea