I am not understanding MySQL Joins at all. I'm stuck - mysql

So I'm trying to learn some MySQL and I have gotten to a point on Joins. It is doing my head in.
I have a few exercises I am trying to work through and getting no where.
The current exercise calls for this:
Use the pre-1994 SQL syntax (i.e. do not use the INNER JOIN syntax) to display the order date, order number and the shipper company name for orders shipped to
Portugal. Sort the output in ascending order of order date.
I currently have typed this:
SELECT OrderDate, OrderID, ShipperID FROM Shippers Orders
WHERE shippers.shipperID = orders.shipperID AND orders.shipcountry = 'Portugal';
But I am getting this error message:
Error Code: 1054. Unknown column 'OrderDate' in 'field list'
What am I doing wrong? Also, what can I provide to help you guys to help me?
OrderDate DOES exist, as you can see here from my screenshot here of 'Select * from Orders'
So I imagine that is similar but with a different join process.
Thank you in advance!

You have to use table name with column names to identify that which column belongs to which table.
SELECT orders.OrderDate, orders.OrderID,shippers.ShipperID FROM Shippers, Orders
WHERE shippers.shipperID = orders.shipperID AND orders.shipcountry = 'Portugal';
Or you can you aliasing that will be easy to write the query.
SELECT b.OrderDate, b.OrderID, a.ShipperID FROM Shippers a, Orders b
WHERE a.shipperID = b.shipperID AND b.shipcountry = 'Portugal';
Hope this will help.

You can use like this.
SELECT o.OrderDate, o.OrderID, s.ShipperID FROM Shippers s, Orders o
WHERE s.shipperID = o.shipperID AND o.shipcountry = 'Portugal';

Use the pre-1994 SQL syntax
Sounds like the training course is taking you the long way around (though the date is wrong; probably should be 1989)!
The lesson here is that doing a relational product operation between two tables (a.k.a. CROSS JOIN to use the 1992 term, which remains outside core Standard SQL) forces you to use SQL's dot qualified references in the form <range variable reference>.<column reference> in order to disambiguate what would otherwise be duplicated column references (e.g. in your case where shipperID appears in both tables).
I guess the ultimate destination is NATURAL JOIN, where the need for range variables is dispensed with entirely!

Related

Trying to average the results of a count which is grouped?

I am using MySQL and am trying to create a query to solve this question:
Average number of borrowed books by occupation
My plan was to count the number of instances of 'BorrowID' because each time a book is borrowed it creates a unique BorrowID. Then group those by clientID so that each person has their total listed books borrowed. Then this is where I start to get lost, as I obviously want to average all the grouped occupations however I am not sure if I am doing that...
First I tried:
SELECT client.Occupation, AVG(BorrowIDCount)
FROM
(
SELECT COUNT(BorrowID) as BorrowIDCount
FROM client, borrower
WHERE client.ClientID = borrower.ClientID
GROUP BY borrower.ClientID
) as x
GROUP BY Occupation
But it gives the error:
Unknown column 'client.Occupation' in 'field list'
Which I thought was because the outer query needed to know which tables...
So then I tried:
SELECT client.Occupation, AVG(BorrowIDCount)
FROM client, borrower
WHERE client.ClientID = borrower.ClientID AND
(
SELECT COUNT(BorrowID) as BorrowIDCount
FROM client, borrower
WHERE client.ClientID = borrower.ClientID
GROUP BY borrower.ClientID
)
GROUP BY Occupation
It didn't like the alias for the subquery so I removed it although no idea why, however it then gave this error:
Unknown column 'BorrowIDCount' in 'field list'
I feel like I may be completely off base in terms of how to create this query but I also feel that I might be close and am just not understanding some rules or syntax here. Any help in the right direction would be incredibly appreciated.
Thanks!
It looks to me like you want to figure out the number of books borrowed by client, then to average that number by occupation. So let's do it in steps:
First is a subquery to get the books per client.
SELECT COUNT(*) borrowed, ClientID
FROM borrower
GROUP BY ClientID
Next, we use that subquery in an outer query to get the average you want.
SELECT AVG(byclient.borrowed) average_borrowed,
client.Occupation
FROM (
SELECT COUNT(*) borrowed, ClientID
FROM borrower
GROUP BY ClientID
) byclient
LEFT JOIN client ON byclient.ClientID = client.ClientID
GROUP BY client.Occupation
ORDER BY AVG(byclient.borrowed) DESC, client.Occupation;
Your requirement calls for an aggregate of an aggregate, so you must nest one aggregate query inside another.
LEFT JOIN allows the inclusion of clients without any occupation. If you don't want that just use JOIN.
The first query in your question failed because your FROM clause referred to a subquery (a virtual table) that lacks the Occupation column. The second one failed because AND (virtual table) doesn't mean anything in SQL.
This nesting of virtual tables is the Structured part of Structured Query Language.

Create a query to determine which sub_genres come from which regions

SELECT Sub_Genre.sgid, Sub_Genre.sgname, Region.rname
FROM Sub_Genre AS S, Region AS R
JOIN Band_Styles AS bSty ON bSty.sgname=S.sgname
JOIN Band_Origins AS bOri ON bOri.bname=bSty.bname
JOIN Country AS C ON C.cname=bOri.cname
JOIN Region ON R.rname=C.rname
ORDER BY S.sgid;
I am trying to Create a query to determine which sub_genres come from which regions.
I keep getting an Error Code 1054. Unknown column 'Sub_Genre.sgid' in 'field list'
Don't mix explicit and implicit joins. Use standard, explicit joins consistently.
Table region appears twice in the query, first in an implicit join with an alias, and then in a standard join without an alias. This is most likely not what you want.
Columns in the select clause are prefixed with the entire table name, while the table are aliased in the from clause: this is not supported.
This would be a cleaner way to express the logic:
select s.sgid, s.sgname, r.rname
from sub_genre s
join band_styles bsty on bsty.sgname = s.sgname
join band_origins bori on bori.bname = bsty.bname
join country c on c.cname = bori.cname
join region r on r.rname = c.rname
order by s.sgid;
This fixes the syntax problems. Whether this gives the correct results or not is something else: you did not share the structures and data you are working with, so I cannot tell.

inner join with COUNT() and GROUP BY

I am using phpMyAdmin to test this query but keep getting a syntax error. I've tried looking it up in the MySql manual and trying other syntactical possibilities but I've gotten older in this process. Thanks for your help
SELECT image_title, image_id, COUNT(other_sales.*) FROM art
INNER JOIN other_sales ON (art.image_id=other_sales.image_id)
GROUP BY (other_sales.image_id);
MySQL said: Documentation
Documentation
1052 - Column 'image_id' in field list is ambiguous
Ultimately, I want to count the number of times a specific number (image_id) occurs in the 'other_sales' table
To troubleshoot these 1064 errors:
The error message gives a snippet of your query. The first character of the snippet is the first character the MySQL interpreter could not understand.
So in the case of your query, it's
SELECT image_title, image_id, COUNT(other_sales.*) FROM art INNER JOIN ...
ggggggggggggggggggggggggggggggggggggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbb
where g means good and b means bad.
Your actual problem: you can't put more than one value in a COUNT() function. You tried to put COUNT(something.*) which makes no sense to count.
Notice that COUNT(*) is a special case meaning just count the rows.
the tables art and other sales probably both have the column image_id.
specify the table before the column like art.imageid or asign a alias to the table and then to the column like so
SELECT o.image_title, o.image_id, COUNT(*)
FROM art a JOIN other_sales o ON (art.id=other_sales.image_id)
GROUP BY (o.image_id)
Yes, I see that now. There are 2 problems with my original code.
I should have chosen the specific column name instead of using *
image_id is a column name that appears in both tables I am accessing. That will cause an "ambiguous" error.
Below is the original code and the corrected code:
original:
SELECT image_title, image_id, COUNT(other_sales.*) FROM art INNER JOIN other_sales ON (art.image_id=other_sales.image_id) GROUP BY (other_sales.image_id);
corrected:
SELECT image_title, art.image_id, COUNT(other_sales.image_id) FROM art INNER JOIN other_sales ON (art.image_id=other_sales.image_id) GROUP BY (other_sales.image_id);
thanks for the help

MySQL Inner Join Query Syntax error

I'm kind of a MySQL novice and can't figure out what is going wrong here. I have two tables. The left table is called Workouts. The relevant columns are date (type date) and id (type int).
The right table is called Workout_locations (relevant fields: workout_id type int, and location_id type int).
The join fields are Workouts.id and Workout_locations.workout_id.
All I want to do is get a table of two columns: date (from Workouts), and location_id (from Workout_locations). I need to only pull records from the Workouts table based on a couple of fields (the sql statement should make this clear).
Here is my sql syntax:
SELECT Workouts.date as date, Workout_locations.location_id as loc_id
FROM Workouts
WHERE Workouts.pacegroup_id='9' AND (Workouts.date BETWEEN '2013-08-19' AND '2013-08-25')
INNER JOIN Workout_locations ON Workouts.id=Workout_locations.workout_id"
But I get this error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'INNER JOIN Workout_locations ON
Workouts.id=Workout_locations.workout_id' at line 1
I'm hoping that this is a very easy error to spot for someone who is experienced with this. Can anyone see it? Thanks!
Your INNER JOIN should come before the WHERE. I also don't think you needed the parens around your BETWEEN clause, but I doubt that it'll cause an error either way:
SELECT Workouts.date as date, Workout_locations.location_id as loc_id
FROM Workouts
INNER JOIN Workout_locations ON Workouts.id=Workout_locations.workout_id
WHERE Workouts.pacegroup_id = '9'
AND Workouts.date BETWEEN '2013-08-19' AND '2013-08-25';
Also, though they technically let you get away with it, you should avoid using "date" as a selected column name (it's a reserved word).
You could do a bit of streamlining as well to make things a bit easier to read:
SELECT Workouts.date AS wo_date, Workout_locations.location_id AS loc_id
FROM Workouts w
INNER JOIN Workout_locations l ON w.id = l.workout_id
WHERE w.pacegroup_id = '9'
AND w.date BETWEEN '2013-08-19' AND '2013-08-25';

MySQL joins confuse me and I always get syntax errors

I need to fetch some data from a MySQL db. I have the function working using two separate, simple queries, but i'm sure this is probably achievable with one query using a JOIN. SQL isn't my strong point and I keep getting syntax errors when I try. Sure, I could leave it as it is, why not, it works. But i would prefer to see a real world example of how they can be joined so i can try and apply it on other queries in the future.
Query one is:
select manufacturers_id from products where products_name = product a
The result is then put into a variable and used in the following
select manufacturers_name from manufacturers where manufacturers id = $man_id
So, basically, the products table holds the manufacturers_id, which we need to collect for a given product to find out what the manufacturers name is from the manufacturers table.
manufacturers_id is the common field.
Try this:
SELECT b.manufacturers_name
FROM products a
LEFT JOIN manufacturers b ON a.manufacturers_id = b.manufacturers_id
WHERE a.products_name = 'PRODUCT NAME'
Below is a diagram of SQL Joins
Image Source
Try this:
select m.manufacturers_name from products p, manufacturers m
where p.products_name = 'productA' and p.manufacturers_id = m.id
I believe this is what you're looking for
SELECT manufacturers.manufacturers_name
FROM products
JOIN manufacturers on manufacturers_id=products.manufacturers_id
WHERE manufacturers_name='product a'
With a join, you just need to follow this syntax, and remember that you have to set the matching columns equal to each other so you don't end up with invalid rows.
I'd show you how the equivalent of this using table joins, but I really don't want to encourage the use of that syntax, even by accident.