I have 2 tables.
First table - products
products_id | quantity
1001,1
1002,2
1003,5
1004,4
Second table - products_catalog
products_catalog_id | products_id | partner_channel |active_status
1,1001,amazon,0
2,1001,ebay,0
3,1001,zalando,1
4,1002,amazon,1
5,1002,ebay,0
6,1003,amazon,1
7,1003,ebay,1
8,1003,zalando,1
9,1004,amazon,0
10,1004,ebay,0
11,1004,zalando,0
I want to have result of the products id with the condition if this product is not active in any partner channel (active_status = 0)
I was using WHERE filter like this:
SELECT p.products_id, pc.partner_channel, pc.active_status
FROM products p
LEFT JOIN products_catalog pc ON pc.products_id=p.products_id
WHERE pc.active_status='0'
GROUP BY p.products_id ORDER BY p.products_id;
WHERE active_status = 0, but the result was like this:
products_id | partner_channel | active_status
1001,amazon,0
1002,ebay,0
1004,amazon,0
I want to have result table products like this:
products_id | partner_channel | active_status
1004,amazon,0
Because in all partner_channel only this product id (1004) that have active_status = 0.
I think i missed something in the WHERE filter, but didn't have any clue about that. Maybe i should use sub query in when LEFT JOIN to products_catalog?
Any help will be appreciated.
Thanks.
use Having function.
SELECT p.products_id, ANY_VALUE(pc.partner_channel), ANY_VALUE(pc.active_status)
FROM products p
LEFT JOIN products_catalog pc ON pc.products_id=p.products_id
GROUP BY p.products_id
having sum(pc.active_status)=0
ORDER BY p.products_id;
You have to place a condition in the HAVING clause like this:
SELECT products_id
FROM products_catalog
GROUP BY products_id
HAVING SUM(active_status <> 0) = 0;
This query returns all products_id values having active_status = 0 for all partner_channel they are related to.
You can then use the above query as a derived table to join back to the original tables in order to get the rest of the fields:
SELECT p.*, pc.*
FROM products p
JOIN products_catalog pc ON pc.products_id=p.products_id
JOIN (
SELECT products_id
FROM products_catalog
GROUP BY products_id
HAVING SUM(active_status <> 0) = 0
) AS g ON g.products_id = p.products_id
ORDER BY p.products_id
Demo here
Try this Code
SELECT p.products_id, pc.partner_channel, pc.active_status
FROM products p
LEFT JOIN products_catalog pc ON pc.products_id=p.products_id
WHERE pc.active_status='0'
GROUP BY p.products_id ORDER BY p.products_id DESC;
Related
assuming we have a database category structure like this
# Categories Table
| category_id | parent_category_id | status |
# Products Table
| product_id | category_id |
how do i get the list of products in a category only if the parent_category_id has an active status = 1 ?
i guess i could use some sub-query in the SELECT statement, but i don't know how! :(
something like:
SELECT p.*, (SELECT * FROM ? WHERE ? ) AS x
FROM products AS p
LEFT JOIN categories AS c ON p.category_id = c.category_id
WHERE ...
AND p.product_id = '?'
AND ...
Thank you in advance for any advice!
NB: i'm using PHP as backend language, just in case i need some sort
of data manipulation to pass to the mysql query.
try not to use subquery, because it can affect the speed of loading data
maybe it can help
SELECT *
FROM categories c
INNER JOIN products p ON p.category_id=c.category_id
WHERE c.status = 1
Here a example query, I don't use left join or join, becasue you require that the record exists in order to get the status.
SELECT
*
FROM
products, categories
WHERE
products.category_id = categories.category_id
AND status = '1'
SELECT p.* FROM products p
INNER JOIN categories child ON child.category_id = p.category_id
INNER JOIN categories parent ON parent.category_id = child.parent_category_id
WHERE parent.status=1
First you have to get all active categories
SELECT child.*
FROM Categories child
JOIN Categories parent
ON child.parent_category_id = parent.category_id
AND parent.status = 1
But you also need the root categories with not parent_id
SELECT *
FROM Categories
WHERE parent_category_id IS NULL
AND status = 1
So you UNION both
SELECT *
FROM Categories child
JOIN Categories parent
ON child.parent_category_id = parent.category_id
AND parent.status = 1
UNION ALL
SELECT *
FROM Categories
WHERE parent_category_id IS NULL
AND status = 1
Now you get the products for those categories
SELECT *
FROM ( ... UNION ALL ... ) active_categories
JOIN Products
ON active_categories.category_id = Product.category_id
I have 3 tables products,colors,assign with this structure:
products:
product_id | default_color
1 | 1
colors
color_id | color_name
1 | Black
2 | Green
3 | Yellow
assign
product_id | color_id
1 | 1
1 | 2
1 | 3
My query returns only first row from "assign" table, I need to have ALL colors assigned for current product.
Here is a query I use:
SELECT * FROM products p
LEFT JOIN assign a ON p.product_id = '1'
LEFT JOIN colors c ON a.color_id = c.color_id
WHERE p.product_id = 1
Try this:
SELECT * FROM products p
LEFT JOIN assign a ON a.product_id = p.product_id
LEFT JOIN colors c ON c.color_id = a.color_id
WHERE p.product_id = 1
The join condition should be made on column names, not on values.
For filtering results, use where.
See here a working sqlFiddle.
For more info on join, see the official docs here.
Instead of p.product_id = '1' use a.product_id
SELECT * FROM products p
LEFT JOIN assign a ON p.product_id = a.product_id
LEFT JOIN colors c ON a.color_id = c.color_id
WHERE p.product_id = 1`
Your SQL statement seems to list all three rows from assign table.
I executed your query:
SELECT * FROM products p
LEFT JOIN assign a ON p.product_id = '1'
LEFT JOIN colors c ON a.color_id = c.color_id
WHERE p.product_id = 1
And I am getting the three rows of assign table.
Here is my SQLFiddle: http://sqlfiddle.com/#!9/50f8bd/1/0
Try this query. Everything is the same as yours except I'm using GROUP_CONCAT() function to concatinate ALL colors for a given product into one field.
SELECT
p.product_id,
GROUP_CONCAT(c.color_name ORDER BY c.color_name ASC SEPARATOR ', ') AS colors
FROM products p
LEFT JOIN assign a ON a.product_id = p.product_id
LEFT JOIN colors c ON c.color_id = a.color_id
WHERE p.product_id = 1
RESULT:
product_id | colors
-----------|-------------
1 | Black, Green, Yellow
DEMO:
http://sqlfiddle.com/#!9/50f8bd/6
I have the following query, where i want to get the total number of rows but this seems to count each individually here is the query and the result
SELECT
COUNT(pc.product_id)
FROM
products as p
INNER JOIN product_categories as pc
ON p.product_id = pc.product_id AND pc.subcategory_id IN (77)
GROUP BY pc.product_id
HAVING COUNT(pc.subcategory_id) = 1
Result is :
COUNT(pc.product_id)
1
1
1
...but it should be
COUNT(pc.product_id)
3
UPDATE
the above query should count the number of products that are get by this query
SELECT
*
FROM
products as p
INNER JOIN product_categories as pc
ON p.product_id = pc.product_id AND pc.subcategory_id IN ($sb_2)
GROUP BY pc.product_id
HAVING COUNT(DISTINCT pc.subcategory_id) = $sb_count
$sb_2 = 77,76;
$sb_count = how many values are in $sb_2;
77 and 76 are different subcategories ids but are common for some products
If you know another way to count this or to make another query...
SELECT
COUNT(pc.product_id)
FROM
products as p
INNER JOIN product_categories as pc
ON p.product_id = pc.product_id AND pc.subcategory_id IN (77)
HAVING COUNT(pc.subcategory_id) = 1
Removing the group by should do the trick.
I manage to count rows by the following query.
"SELECT COUNT(*) as count FROM (SELECT
*
FROM
product_categories WHERE subcategory_id IN (77,76)
GROUP BY product_id
HAVING COUNT(DISTINCT subcategory_id) = 2) as subc";
}
i try to list out all products with product images, but not sure how to use subquery in this situation. Below is my database structure
products
products_id + product_name +
1 | Apple |
2 | Banana |
products_screenshot
products_id + images +
1 | Apple-1.jpg |
1 | Apple-2.jpg |
1 | Apple-3.jpg |
2 | Banana-1.jpg |
2 | Banana-2.jpg |
2 | Banana-3.jpg |
this is my query:
$sql = "SELECT p.* FROM `products` p ORDER BY p.products_id ASC ";
//LEFT JOIN (SELECT ps.* FROM `products_screenshot` ps WHERE ps.products_id=p.products_id) AS pss ON(p.products_id=pss.products_id)
$query = $db->query($sql);
while ($row = $query->fetch_object()) {
// result
echo $row->products_name.'</br>';
// list all product screenshot related with this
//$row->images
}
With your requirement you can do as below. Then execute the query and loop through.
The
$row->images will be comma seperated and you can split them display them for a product.
$sql = "SELECT p.products_id,p.product_name,group_concat(pi.images) as `images`
FROM `products` p
left join products_screenshot pi on pi.products_id = p.products_id
group by p.products_id
ORDER BY p.products_id ";
If you dont care about products being repeated multiple times in the loop then just use below where for each loop you will get a new row with the product and the related images
$sql = "SELECT p.products_id,p.product_name,pi.images
FROM `products` p
left join products_screenshot pi on pi.products_id = p.products_id
ORDER BY p.products_id ";
What wrong with a simple query like this:
select
p.products_id,
p.product_name,
ps.images
from
products p
join products_screenshot ps
on p.products_id=ps.products_id
where
whateveryouline
order by
1,2
It will get you all the items you need?
Try this query:
select products.product_name, products_screenshot.images from products,products_screenshot where products.products_id = products_screenshot.products_id
SELECT * from products_screenshot as ps where products_id IN (SELECT p.products_id from products as p WHERE p.products_id = ps.products_id )
I'm trying to create a rating system, where the user can rate pictures/videos/audio etc. I have two tables at the moment
Table: products
Cols: product_id[PK] | name | category | type | link
This is the products table and contains information about the products. If you're confused by products, think of the "product" as the image/video/audio, I named it like this simply for allowing me to understand it easier. The second table is the ratings
Table: product_ratings
Cols: rating_id[PK] | rating | product_id | timestamp
This table stores information about the rating the user has given.
I want a page where it will display the highest rating (on average) for all "products". So far, I've looked through SA, and found the follow piece of code:
SELECT
p.product_id, p.name,
AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN product_ratings pr
ON pr.product_id = p.product_id
WHERE p.product_id = 1
This just returns the average rating for a specific product_id, How would I go about getting ALL the product_ids and their average rating, and how would I find the highest one via PHP?
I've tried:
WHERE p.product_id < 1 AND p.product_id < 30
But this just returns product_id of 2, with it's name and average_rating, which I don't understand.
Guidance/links to material are welcome
SELECT
p.product_id,
p.name,
AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN product_ratings pr
ON pr.product_id = p.product_id
GROUP BY p.product_id
ORDER BY rating_average DESC
LIMIT 1
Just try:
SELECT
p.product_id, p.name,
AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN product_ratings pr
ON pr.product_id = p.product_id
also this is meaningless expression:
WHERE p.product_id < 1 AND p.product_id < 30
because it is completely equivalent to
WHERE p.product_id < 1
and i doubt that you have ids below zero
Your query is close. Just remove the WHERE clause that filters everything.
SELECT p.product_id, p.name,
AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN product_ratings pr
ON pr.product_id = p.product_id
ORDER BY rating_average DESC
This will return you the averages for each product, sorted with the highest average rating at the top of the resultset.