MySQL nested selection - mysql

I am trying to figure out this question on a practice page online with the following tables:
Question:
For all cases in which the same customer rated the same product
more than once, and in some point in time gave it a lower rating
than before, return the customer name, the name of the product,
and the lowest star rating that was given.
I cant seem to figure out why this isnt correct - would anyone be able to help?

Here is what I have so far (without sample data):
SELECT
Customer.customer_name,
Product.product_name,
MIN(Rating.rating_stars)
FROM Rating
JOIN Product ON Rating.prod_id = Product.prod_id
JOIN Customer ON Rating.cust_id = Customer.prod_id
GROUP BY Customer.customer_name, Product.product_name
HAVING COUNT(Product.prod_id) > 1

This query will return the minimum rating stars of a product that has been reviewed more than once by the same customer, with any of the newer ratings lower than an older rating:
SELECT
r1.prod_id,
r1.cust_id,
MIN(r1.rating_star) AS min_rating
FROM
rating r1 INNER JOIN rating r2
ON r1.prod_id=r2.prod_id
AND r1.cust_id=r2.cust_id
AND r1.rating_date>r2.rating_date
AND r1.rating_star<r2.rating_star
GROUP BY
r1.prod_id,
r1.cust_id
you can then join this query with products and customers table:
SELECT
customer.customer_name,
product.product_name,
m.min_rating
FROM (
SELECT
r1.prod_id,
r1.cust_id,
MIN(r1.rating_star) AS min_rating
FROM
rating r1 INNER JOIN rating r2
ON r1.prod_id=r2.prod_id
AND r1.cust_id=r2.cust_id
AND r1.rating_date>r2.rating_date
AND r1.rating_star<r2.rating_star
GROUP BY
r1.prod_id,
r1.cust_id) m
INNER JOIN customer on m.cust_id = customer.cust_id
INNER JOIN product ON m.product_id = product.product_id

Just a few points:
You cant specify the tables in the FROM clause the sane way you specify attributes in the SELECT. You can only have a single table in the FROM, and one more for each Join you use.
SELECT a, b, c FROM a; <----------fine
SELECT a, b, c FROM a, b; <----not fine
SELECT a, b, c FROM a JOIN b; <---fine
When it comes to the tables in the FROM/JOIN, you dont use "AS" to give them an alias, just the table name followed by the alias.
FROM atable a JOIN btable b; <--This assigns alias a to "atable" and b to "btable".
You also have to specify the common attribute that the tables are going to be joined on:
customer JOIN rating ON customer.cust_id = rating.cust_id;
As for the rest you can probably work out the correct WHERE clauses to use once you have the syntax down.

Related

mysql count rows from two tables in one query?

I have two MySQL-tables:
Persons (pid,name,companyID,companyName)
Orders (oid,companyID,details)
Now I want to count the number of order_id for each companyName as following:
Name Total
-------------------
CompanyName1 : 1200
CompanyName2 : 758
CompanyName3 : 11
I used this query but it's not working properly.
SELECT count(o.oid) as total,p.companyName
FROM orders as o, persons as p
WHERE o.companyID = p.companyID
GROUP BY p.companyName
Use join and group the result by p.companyID
SELECT p.companyName, count(o.oid) as total
FROM orders as o join persons as p
on o.companyID = p.companyID
GROUP BY p.companyID
If you are missing the companies without any orders you can use a left join.
SELECT p.companyName, count(*) as total
FROM persons p
LEFT JOIN orders o ON o.companyID = p.companyID
GROUP BY p.companyID, p.companyName
Please do not use the old, legacy join syntax any more - it is outdated since 1992.
Your data model looks messed up. That you have company ids and names in the person table but no corresponding companies table is highly suspicious.
In any case, presumably there can be multiple rows per company. You can condense the persons table and then join:
SELECT c.companyName, COUNT(*) as total
FROM orders o JOIN
(SELECT DISTINCT companyId, companyName
FROM persons p
) c
ON o.companyID = c.companyID
GROUP BY c.companyName;
However, you should fix the data model so you have a real bona fide companies table -- especially because you seem to care about that entity.

How to avoid Left join table show duplicate row?

I have some problem with the query issue when trying to sum up the quantity.
Table
This cart item table stored id_cart and id product
This order table stored id_cart and other id may be included such as supplier. This table is used to track order record and send notification to supplier.
Wrong result. Expected output = 1, 1, 1
SELECT id, id_product, SUM(qty)
from cart_item
left join Orderp using(id_cart)
group by id_product
http://sqlfiddle.com/#!9/07bf57/1
The issue caused by duplicate id_cart in order table as well. How can i handle this? Any solution to make it works? Thanks.
There is something wrong in your data, or in your data model
INSERT INTO OrderP(`id_order`,`id_cart`)VALUES(1, 1);
INSERT INTO OrderP(`id_order`,`id_cart`)VALUES(2, 1);
There are 2 rows for id_cart = 1, so the "natural join" will double every row when joining cart_item to orderp.
Using an inner join to a different column in orderp works better because now there is only one row in orederp for each cart_item.
SELECT id_product, sum(qty)
from cart_item ci
left join Orderp o on ci.id_cart = o.id_order
GROUP BY id_product
http://sqlfiddle.com/#!9/07bf57/13
Try the following query
SELECT
i.id_product,
p.name productname,
b.id_branch,
b.branchname,
SUM(i.qty)
from cart_item i
left join (SELECT DISTINCT id_cart,id_branch FROM Orderp) o on o.id_cart=i.id_cart
left join product p on i.id_product=p.id_product
left join catalog c on c.id_product=p.id_product and c.id_branch=o.id_branch
left join branch b on b.id_branch=o.id_branch
group by
i.id_product,
p.name,
b.id_branch,
b.branchname
The main problem in Orderp table because it containts two different orders for one cart (DISTINCT id_cart,id_branch helps here). And you need to use the second condition by id_branch for catalog (and c.id_branch=o.id_branch).
SQL Fiddle - http://sqlfiddle.com/#!9/f32d5f/16
And I think you can use everywhere INNER JOIN instead LEFT JOIN
SELECT
i.id_product,
p.name productname,
b.id_branch,
b.branchname,
SUM(i.qty)
from cart_item i
join (SELECT DISTINCT id_cart,id_branch FROM Orderp) o on o.id_cart=i.id_cart
join product p on i.id_product=p.id_product
join catalog c on c.id_product=p.id_product and c.id_branch=o.id_branch
join branch b on b.id_branch=o.id_branch
group by
i.id_product,
p.name,
b.id_branch,
b.branchname

Joining multiple MySQL Tables with one relations ID

I have 4 MySQL tables on identity column is in common between all these tables,
Tables in Sequence:
1- Items.
2- Sales.
3- Puchases.
4- Returned.
ItemID appears in all of these tables, WHEN i use LEFT JOIN i get duplicates like:
select
a.ItemID AS ItemID,
a.Item_title AS ItemTitle,
SUM(b.qty) AS SoldQty,
SUM(c.qty) AS PurQty,
SUM(d.qty) AS RetQty
from items a
left join sales b on a.ItemID = b.items_ItemID
left join purchases c on a.ItemID = c.items_itemID
left join returned d on a.ItemID = d.items_ItemID
group by a.ItemID
That query was one of the many tries that i've tried :D the result i get is always unique for sales but duplicates for other tables ..
Thanks for the answer.
If I understand what you're trying to do correctly, you want the total number of sales, purchases, returned etc per item id from a. If that's the case, try thinking about an easier piece of the problem first: how do I get the sum of each sales quantity, grouped by item id?
To do that you'd do something like:
select b.items_ItemID, sum(b.qty) as total_sales_qty
from sales b group by b.items_ItemID
You could do the same thing for tables c and d.
Once you've got those, you can join them all together like this:
select a.ItemID, bb.total_sales_qty, cc.total_purchases_qty, dd.total_returned_qty
from items a
left join (
select b.items_ItemID, sum(b.qty) as total_sales_qty
from sales b group by b.items_ItemID) bb
on a.ItemID = bb.items_ItemID
left join (
select c... etc) cc
on a.ItemID = cc.items_ItemID
... etc
I don't really use MySQL, but in SQL Server, you could use the distinct directive, so duplicate rows appear as just a single row. All the returned columns must be identical, mind you.
Select Distinct a.ItemID AS ItemID,... From....
Hope this helps

SQL Join, right ? left ? inner?

working with mySql I would like to list all purchases that customers made on a specific cathegory of products.
So, I had 3 tables: customers (idCustomer, Name) , cathegories (idCategory, CategoryName) and orders (idOrder, idCustomer, idCathegory, Qty, Price)
But I want a listing with ALL of the customers.
Not only the one who bought that specific idCategory
I thought something like:
select sum(Orders.Qty), Customers.Name
from Orders
right join Customers on Orders.idCustomer = Customer.idCustomer
where Orders.idCategory = 'Notebooks'
group by Orders.idCategory
but this statement only lists the records for customers who exists in Orders table.
And I want all of them ( the one who didnt buy, with qty =0 )
thanks in advance
Most people find left join easier to follow than right join. The logic for left join is to keep all rows in the first table, plus additional information from the remaining tables. So, if you want all customers, then that should be the first table.
You will then have a condition on the second table. Conditions on all but the first table should be in the on clause rather than a where. The reason is simple: when there is no match, then the value will be NULL and the where condition will fail.
So, try something like this:
select sum(o.Qty) as sumqty, c.Name
from Customers c left join
Orders o
on o.idCustomer = c.idCustomer and
o.idCategory = 'Notebooks'
group by c.Name;
Finally, the group by should have a relationship to the select clause.
Try this query
select sum(Orders.Qty), Customers.Name
from Customers
right join Orders on Customer.idCustomer = Orders.idCustomer and Orders.idCategory = 'Notebooks'
group by Customers.Name

Mysql + difference in two result sets

I have a pretty simple MySQL question. I have two tables, Customer and Orders. Customer table has fields (id, name) and Order has fields (id, customerID, and item).
I can find which customer bought product A and customers that bought product B with the following query in MySQL.
SELECT DISTINCT c.`id`, c.name, o.`item`, o.qty FROM `customer` as c
INNER JOIN order AS o ON (c.`Id` = o.`customerID`)
where o.`item` ="Product A"
Union
SELECT DISTINCT c.`id`, c.name, o.`item`, o.qty FROM `customer` as c
INNER JOIN order AS o ON (c.`Id` = o.`customerID`)
where o.`item` ="Product B"
How can find the difference and similarity in these two result sets?
1) I.e. Customers that bought only product A but did not by product B
2) I.e. Customers that bought both product A and B
Thank you for your assistance.
D
You can try using the LEFT OUTER JOIN to get the result.