I have some tables:
products
--------------------------
|p_id|col|col...|...|cat_id|
colors
-----------
|id|p_id|url|
I want select apropriate rows from first table after join to this result another column selected by apropiate id.
In other words I select all products on some cathegory and how many colors each product has.
For example
select *
from products p
where p.p_id = some_number
and join to this
select count(*)
from colors c
where c.p_id = p.p_id
Thanks in advance
Left join return all row of left table(products) even row's id are not match of right table. for more info click here
SELECT p.p_id, COUNT(*) AS colours_count
FROM products AS p
LEFT JOIN colors c
ON c.p_id=p.p_id
GROUP BY p.p_id
Try this:
select p.p_id, count(*) as number_of_colours
from products as p
left join colors c on c.p_id=p.p_id
group by p.p_id
The LEFT JOIN operation guarantees that all rows of table products will be returned. Grouping by p_id, we get a separate row for each product along with the number of colours each product is associated to.
You can do the LEFT JOIN, but note that this returns a row from the left hand table irrespective of whether there is a matching row on the right hand table. Hence it there is no match or 1 match you will still get 1 row returned. As such if you use COUNT(*) you will get a count of 1.
So get around this you count the occurrences of a field from the right hand table (normally the primary key). Used like this COUNT() returns the count of non null fields, so it will return 0 when there is no matching row on the right:-
SELECT p.p_id,
COUNT(c.id) AS number_of_colours
FROM products p
LEFT OUTER JOIN colors c ON c.p_id = p.p_id
GROUP BY p.p_id
Related
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
I have three tables as below, each product may belong to multiple categories.
PRODUCT TABLE AS P
1. ID
2. NAME
CATEGORY TABLE AS C
1. ID
2. NAME
RELATION TABLE AS R
1. ID
2. P_ID
3. C_ID
Now I want to get a list of all products in product table, and with their belonging category name display as well.
How do I write this query?
I can get the category ids pulled from the same query, but don't know how to get all the name pulled as well. Here's what I tried.
select p.*,y.*
from p
left join (select p_id,group_concat(c_id) as category_ids
from relation group by p_id) as y on p.id=y.p_id
Do both JOIN operations (to the relation table, and from there to the table containing the category names) and feed the result to your aggregation function (GROUP_CONCAT)
SELECT P.Name, GROUP_CONCAT(DISTINCT C.Name ORDER BY C.Name SEPARATOR '|') categories
FROM Product P
LEFT JOIN Relation R ON P.ID = R.P_ID
LEFT JOIN Category C ON R.C_ID = C.ID
GROUP BY P.ID, P.Name
This will give you one row per product with the categories separated by |.
This uses LEFT JOIN operations so it won't suppress products that have no categories.
Select P.Name, C.Name
From RELATION R Inner Join PRODUCT P
On R.P_ID=P.Id
Inner Join Category C
On C.Id=R.C_ID
This query will get you all the products, with their corresponding category.
I want to give you a small explanation about the difference between Inner Join and Left Join.
If we take as an example 2 tables :
TA(idA, description) and TB(idB, idA, description).
Select TA.description, TB.description
From TA Inner Join TB On TA.IdA = TB.IdA
will get only the rows in TA, that have a corresponding one in TB.
On the other side,
Select TA.description, TB.description
From TA Left Join TB On TA.IdA = TB.IdA
will get all the rows of TA and if the row in TA doesn't have a corresponding one in TB, TB.description for this row will be NULL.
Hope this helps!
Select distinct is returning indistinct rows. Why?
I want to return distinct shops.
Here is my sql statement:
SELECT
DISTINCT s.*, p.p_id
FROM
shop s
INNER JOIN product_shop ps on s.s_id = ps.s_id
INNER JOIN product p ON p.p_id = ps.p_id
WHERE
s.country = 'new zealand'
Here is the result:
The product (p.p_id) needs to not be distinct, as I want to return a list of shops that have a specific product. But the Shop needs to be distinct.
What am I doing wrong?
Returned rows are distinct. Distinct is applied to all returned row, not to single column. Yes, p_id is same for two rows. But if you compare all columns, there are differences between them.
If you want distinct shops - don't include in select columns from other tables, because it can cause duplicates as in your example.
Simply don't include p.p_id within your selection.
I.e.
SELECT DISTINCT
s.*
FROM shop s
....
Well, If you will look at your entire output, you can see the p_id(the last column) is different for each row. Distinct applies to the entire record, not just one column.
You can either drop the p_id from your select, or use group by and decide which one of the p_id you want, perhaps max? :
SELECT
s.*, max(p.p_id)
FROM
shop s
INNER JOIN product_shop ps on s.s_id = ps.s_id
INNER JOIN product p ON p.p_id = ps.p_id
WHERE
s.country = 'new zealand'
GROUP BY s.id
i need to sort left join by company id so that categories selected by companies will appear first.
My category table is
company_category table is
expected result should be
I am supposing below query is best solution rather than using union to show company categories on top.
SELECT * FROM category c
LEFT JOIN company_category cc ON c.category_id=cc.category_id AND cc.company_id=1
ORDER BY cc.company_id DESC
I need help for my query:
SELECT
P.ID,
P.CategoryID,
P.Name,
P.SupplierID,
p.UnitPrice,
p.UnitsInStock,
pp.PicturePath
FROM Products P JOIN ProductPhoto PP ON p.ID=PP.ProductID WHERE P.CategoryID='2';
This query gives me 2 results but it must give me 4 result because there are 4 data whose categoryID='2'
Also I have checked from this query and there are 4 data whose categoryID='2'
select * from Products;
You will want a LEFT JOIN:
SELECT P.ID,
P.CategoryID,
P.Name,
P.SupplierID,
p.UnitPrice,
p.UnitsInStock,
pp.PicturePath
FROM Products P
LEFT JOIN ProductPhoto PP
ON p.ID=PP.ProductID
WHERE P.CategoryID='2'
A LEFT JOIN will return all Products even if there is no matching row in the ProductPhoto table. The INNER JOIN will only return rows that match in both tables.
If you need help learning JOIN syntax then here is a great visual explanation of Joins
SELECT
P.ID,
P.CategoryID,
P.Name,
P.SupplierID,
p.UnitPrice,
p.UnitsInStock,
pp.PicturePath
FROM Products P LEFT JOIN ProductPhoto PP ON p.ID=PP.ProductID WHERE P.CategoryID='2'
Try use left join, it is possible that there is no productionPhoto records matching product.
Note that you are doing an INNER JOIN onto ProductPhoto on the ProductID which equals the ID within Products.
If there are only 2 matching rows in both tables with a categoryID of 2, then that's all you will see returned.
Change your query to be a LEFT JOIN and see if your 4 rows returned. If they are, then your above query is correct.