I'm learning SQL on Test sites and can not get past this question. (Test Dome)
Each item in a web shop belongs to a seller. To ensure service quality, each seller has a rating.
The data are kept in the following two tables:
TABLE sellers
id INTEGER PRIMARY KEY,
name VARCHAR(30) NOT NULL,
rating INTEGER NOT NULL
TABLE items
id INTEGER PRIMARY KEY,
name VARCHAR(30) NOT NULL,
sellerId INTEGER REFERENCES sellers(id)
Write a query that selects the item name and the name of its seller for each item that belongs to a seller with a rating greater than 4. The query should return the name of the item as the first column and name of the seller as the second column.
I've tried the following which has gotten me closest of my attempts:
SELECT items.name, sellers.name
FROM sellers, items
WHERE sellers.rating > 4;
Thanks in advance for bothering with my noob question.
You were almost there but you forgot to specify the join condition, without which would be a cross join (all possible combinations of both table rows)
SELECT items.name, sellers.name
FROM sellers, items
WHERE sellers.rating > 4
AND items.sellerId = sellers.id;
In a more extended form the above should be the same as below
SELECT items.name, sellers.name
FROM sellers
INNER JOIN items
ON sellers.id = items.id
WHERE sellers.rating > 4;
You want to join the tables.
Here's a link to the tutorial on w3s, this topic is explained quite well here: https://www.w3schools.com/sql/sql_join.asp
Related
I have a database I am making with Microsoft Access 2013, where there is 2 tables. First table has productID as the primary key, second table has a unique reviewID as well as the productID of the product that the review is referring to. In first table where the products information is kept, I want to have a field that averages the ratings that it was given in it's reviews (kept in second table).
How do I average it's rating without averaging the rating for all reviews, and only for reviews about that specific product?
Based on your descriptions I've created a table called tblProducts with the following data:
I've then created a table called tblReview with the following data (here I've assumed you have a field to store a value for each review's rating that I've called ReviewRating.. and I've assumed that reviews are rated from 0-10):
I then created this query:
SELECT tblProducts.ProductName, Avg(tblReview.ReviewRating) AS AvgOfReviewRating
FROM tblReview INNER JOIN tblProducts ON tblReview.productID = tblProducts.productID
GROUP BY tblProducts.ProductName;
...which results in:
Note that this is a SELECT query, so it won't put the average review rating in to the original tblProducts table, for that you would need an UPDATE query. I wouldn't recommend that though as you'll have to remember to run the update before using tblProducts for anything that needs up-to-date averages.
me being a humble sql beginner, I have a question: let's say I have two tables: Items, and People(to whom an item is sold). Is there any way in SQL to produce a query to show data of a person who bought the most items, and the ammount of items he or she bought?
my creates are:
CREATE TABLE PEOPLE (
ID INT PRIMARY KEY,
(other data)
);
CREATE TABLE ITEMS (
ID INT PRIMARY KEY,
(other stuff....)
bought_by INT REFERENCES PEOPLE
);
Any help would be appreciated:)
Yes, you can just group by bought_by from ITEMS table, sort the result descending by the count and get the top record:
select top 1 bought_by, count(*)
from ITEMS
group by bought_by
order by count(*) desc
Probably this query can help you too, if you need more people data/info:
SELECT TOP 1 PEOPLE.*, COUNT(ITEMS.*) AMOUNT FROM PEOPLE
JOIN ITEMS ON PEOPLE.ID = ITEMS.bought_by
GROUP BY PEOPLE.ID, PEOPLE.OtherFieldsInPeopleTable
ORDER BY COUNT(ITEMS.*) DESC
Does anyone know how to select all rows from a table with same value of FK without giving its value ? I have a database with warehouse. It has sectors and items of certain values in each sector . I want to select the sectors where overall value of items bigger than a certain number with a single query . And i want the query to be universal - it should sum up overall values of items in every sector of the warehouse ( without specyfing number of secotrs or how many sectors are there ) Anyone knows how to do it ? I don't need a full query, just a way to say my database that it to sum up all values in certain sectors. SectorID is the Foreign Key and Item is the table ( with ItemID as public key and Value as value of item )
I would make use of a combination of queries. Basically, this problem can be solved as below:
Assuming the presence of ID columns in both the Item and Sector tables. Let the value that acts as the threshold T (a certain number returned by a single query as stated above):
Use an inner query to select sector.sectorid, Item.itemid and Item.value by joining the Sector and Item tables on the Item.SectorID = Sector.SectorID Where Item.value > T
Sum(Item.value) on the result obtained from the inner query above and GROUP BY(SECTORID), GROUPBY(ITEMID).
You seem to want a group by query. This is pretty basic, so I assume you are pretty new to SQL:
select SectorId, sum(itemValue) as TotalItemValue
from warehouse w
group by SectorId
having sum(itemValue) > YOURVALUEHERE;
If you want the items in the sectors, then you can get that with a join or in:
select *
from warehouse w
where SectorId in (select SectorId
from warehouse
group by SectorId
having sum(itemValue) > YOURVALUEHERE
)
I have 3 data tables.
In the entries data table I have entries with ID (entryId as primary key).
I have another table called EntryUsersRatings in there are multiple entries that have entryId field and a rating value (from 1 to 5).
(ratings are stored multiple times for one entryId).
Columns: ratingId (primary key), entryId, rating (integer value).
In the third data table I have translations of entries in the first table (with entryId, languageId and title - translation).
What I would like to do is select all entries from first data table with their titles (by language ID).
On a top of that I want average rating of each entry (which can be stored multiple times) that is stored in EntryUsersRatings.
I have tried this:
SELECT entries.entryId, EntryTranslations.title, AVG(EntryUsersRatings.rating) AS AverageRating
FROM entries
LEFT OUTER JOIN
EntryTranslations ON entries.entryId = EntryTranslations.entryId AND EntryTranslations.languageId = 1
LEFT OUTER JOIN
EntryUsersRatings ON entries.entryId = EntryUsersRatings.entryId
WHERE entries.isDraft=0
GROUP BY title, entries.entryId
isDraft is just something that means that entries are not stored with all information needed (just incomplete data - irrelevant for our case here).
Any help would be greatly appreciated.
EDIT: my solution gives me null values for rating.
Edit1: this query is working perfectly OK, I was looking into wrong database.
We also came to another solution, which gives us the same result (I hope someone will find this useful):
SELECT entries.entryId, COALESCE(x.EntryUsersRatings, 0) as averageRating
FROM entries
LEFT JOIN(
SELECT rr.entryId, AVG(rating) AS entryRating
FROM EntryUsersRatings rr
GROUP BY rr.entryId) x ON x.entryId = entries.entryId
#CyberHawk: as you are using left outer join with entries, your result will give all records from left table and matching record with your join condition from right table. but for unmatching records it will give you a null value .
check out following link for the deta:
http://msdn.microsoft.com/en-us/library/ms187518(v=sql.105).aspx
really hope someone can help me on this one!
I have 6 tables:
Products
prodid
Prodequipment
prodid
equipclassmain
equipclassor
Equipclasses
classid
Equipfunctions
equipid
classid
Equipment
equipid
Workshopequipment
workshopid
equipid
Products – a list of some products
Equipment – a list of some equipment
Prodequipment – lists what equipment is needed to do a product. You can use equipment listed in equipclassmain or replace it by equipment in equipclassor. Table Products has one to many relation to table Prodequipment, i.e. you will use many different tools (equipment) to produce one product, but you can choose to use anyone in the pair equipclassmain/equipclassor. For instance to frame a photo you can use a wooden frame or plastic frame (one pair) and a cover glass or cover plastic (second pair). You can combine it as you wish, but both pairs should be used: wooden frame with cover glass or plastic frame with cover glass or wooden frame with plastic cover or plastic frame with plastic cover.
Equipfunctions and Equipclasses – Because one piece of equipment can be used in different ways it is not linked directly to table Prodequipment. I have created table Equipclasses where all single use of every possible equipment is listed and table Equipfunctions where I list those single uses for every equipment.
Workshopequipment – lists workshops and equipment they are using.
Now I need a list of products which can be manufactured by two different given workshops (let's say workshopid = 1 and workshopid = 4), i.e. both those workshops have all equipment needed to produce those products. Bear in mind that those workhops don't have to use the same equipment to do so as I described above.
I'm trying with this query:
SELECT prodid FROM Products JOIN (
SELECT workshopid, prodlist, equipclassmain, equipclassor,
if( LOCATE( equipclassmain, prodlist ) >0
AND LOCATE( equipclassor, prodlist ) >0, 1, 0 ) AS pairstatus FROM Prodequipment JOIN
(
SELECT classid FROM Equipclasses JOIN (
SELECT classid FROM Equipfunctions JOIN (
SELECT workshopid, GROUP_CONCAT( equipid ) AS prodlist FROM Workshopequipment
GROUP BY workshopid
)
equipfunclist GROUP BY equipid
) equipclasslist GROUP BY classid
) WorkshopequipmentList HAVING pairstatus = 1 AND workshopid in (1, 4)
) prodbyworkshops ON classid = equipclassmain OR classid = equipclassor
But I get an "Column classid in field list is ambiguous". Any idea what's wrong here?
THANK YOU!
Your query references multiple tables that have a classid column.
Therefore, when you reference classid in the HAVING clause, it doesn't know which table to get the classid for.
You need to write tablename.classid where tablename is the name of the table containing the classid column. (Probably equipclasslist; I didn't look at the query)
It's from the part of the query with:
...
SELECT classid
FROM Equipclasses JOIN (
SELECT classid
FROM Equipfunctions...
Both EquipClasses and the inner query have a classId. You need to specify which you're selecting.