I have like this database tables:
Table categories
x
id
title
description
status
Table products
id
user_id
category_id
description
status
Table product_varieties
id
variety_id
product_id
description
wholesale_price
retail_price
status
total
I have query to get price min
, max
and avg
in each category:
SELECT `categories`.`title`,
min(product_varieties.wholesale_price) AS wholesalePriceMin,
max(product_varieties.wholesale_price) AS wholesalePriceMax,
avg(product_varieties.wholesale_price) AS wholesalePriceAvg,
min(product_varieties.retail_price) AS retailPriceMin,
max(product_varieties.retail_price) AS retailPriceMax,
avg(product_varieties.retail_price) AS retailPriceAvg
FROM `products`
LEFT JOIN `categories`
ON `categories`.`id` = `products`.`category_id`
LEFT JOIN `product_varieties`
ON `product_varieties`.`product_id` = `products`.`id`
WHERE `products`.`id` IN (1,2,3,4)
GROUP BY `products`.`category_id`
Now I need get total users (sellers) of each category by editing my current query.
I tried like this:
SELECT `categories`.`title`,
min(product_varieties.wholesale_price) AS wholesalePriceMin,
max(product_varieties.wholesale_price) AS wholesalePriceMax,
avg(product_varieties.wholesale_price) AS wholesalePriceAvg,
min(product_varieties.retail_price) AS retailPriceMin,
max(product_varieties.retail_price) AS retailPriceMax,
avg(product_varieties.retail_price) AS retailPriceAvg,
(SELECT user_id,
COUNT(*)
FROM products
GROUP BY category_id) AS totalUsers
FROM `products`
LEFT JOIN `categories`
ON `categories`.`id` = `products`.`category_id`
LEFT JOIN `product_varieties`
ON `product_varieties`.`product_id` = `products`.`id`
WHERE `products`.`id` IN (1,2,3,4)
GROUP BY `products`.`category_id`
But my query not work and return error with message:
SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s)
How I can correct my query?
Advertisement
Answer
A “correlated subquery” can be used in the select list of your main query, this query must return just a single value and the “correlation” occurs through the where clause in that some data from the main query is used to locate the wanted data in the subquery.
SELECT
`categories`.`title`
, min(product_varieties.wholesale_price) AS wholesalePriceMin
, max(product_varieties.wholesale_price) AS wholesalePriceMax
, avg(product_varieties.wholesale_price) AS wholesalePriceAvg
, min(product_varieties.retail_price) AS retailPriceMin
, max(product_varieties.retail_price) AS retailPriceMax
, avg(product_varieties.retail_price) AS retailPriceAvg
, (
SELECT COUNT(*)
FROM products AS p
WHERE p.category_id = `products`.`category_id`
) AS totalUsers
FROM `products`
LEFT JOIN `categories` ON `categories`.`id` = `products`.`category_id`
LEFT JOIN `product_varieties` ON `product_varieties`.`product_id` = `products`.`id`
WHERE `products`.`id` IN (1, 2, 3, 4)
GROUP BY `products`.`category_id`
but I suspect this can be further simplified:
SELECT
`categories`.`title`
, min(product_varieties.wholesale_price) AS wholesalePriceMin
, max(product_varieties.wholesale_price) AS wholesalePriceMax
, avg(product_varieties.wholesale_price) AS wholesalePriceAvg
, min(product_varieties.retail_price) AS retailPriceMin
, max(product_varieties.retail_price) AS retailPriceMax
, avg(product_varieties.retail_price) AS retailPriceAvg
, COUNT(products.user_id) AS totalUsers
FROM `products`
LEFT JOIN `categories` ON `categories`.`id` = `products`.`category_id`
LEFT JOIN `product_varieties` ON `product_varieties`.`product_id` = `products`.`id`
WHERE `products`.`id` IN (1, 2, 3, 4)
GROUP BY `products`.`category_id`
or, depending on the data:
, COUNT(DISTINCT products.user_id) AS totalUsers