How do I set the field most_popular to 0 if its count is null with a select statement inside a select statement
i've tried IFNULL(SELECT COUNT(*) ...), 0) as most_popular but it won't work and I tried
COALESCE(SELECT COUNT(*) ...., 0) as most_popular
$stmt = $db->prepare("SELECT *,
i.medium_image, i.width, i.height,
(SELECT COUNT(*) FROM order_details od WHERE od.product_id = p.product_id) as most_popular
FROM products p
INNER JOIN product_images i on i.product_id = p.product_id
WHERE p.department_id=:department_id AND p.is_active=1
$orderby
LIMIT :limit OFFSET :offset");
Try this,
SELECT *,
i.medium_image,
i.width,
i.height,
COALESCE(s.totalCount, 0) most_popular
FROM products p
INNER JOIN product_images i
ON i.product_id = p.product_id
LEFT JOIN
(
SELECT product_id, Count(*) totalCount
FROM order_details
GROUP BY product_id
) s ON s.product_id = p.product_id
WHERE p.department_id = :department_id
AND p.is_active = 1
$orderby
LIMIT :limit OFFSET :offset
or how about this, (your current query)
COALESCE((SELECT COUNT(*)
FROM order_details od
WHERE od.product_id = p.product_id), 0) as most_popular
Related
I want to select database with condition but not working.
I have this query :
SELECT c.*
,s.*
,f.*
,count(c.id) as instock_count
,totals.orders_total
,GROUP_CONCAT(c.sku SEPARATOR '<br/>') AS sku
FROM produse_com c
INNER JOIN (SELECT * , SUM(stoc) as stoc_sum
FROM stocuri_mentor
GROUP BY sku ) s
ON c.sku = s.sku
INNER JOIN (SELECT count(id) as orders_total, id_comanda
FROM produse_com
WHERE NOT ridicat = 'Da'
GROUP BY id_comanda ) totals
ON totals.id_comanda = c.id_comanda
INNER JOIN (SELECT data_add, status, id_comanda
FROM comenzi
WHERE NOT (status = 'Impachetat' OR status = 'Stornat' OR status = 'Anulat')
) f
ON f.id_comanda = c.id_comanda
WHERE stoc_sum >= c.qty
GROUP BY c.id_comanda
HAVING instock_count = orders_total
The issue is I have a condition WHERE NOT ridicat = 'Da'
But the result contain all result with ridicat = 'Da'
EDIT :
If I remove this query INNER JOIN (SELECT * ,SUM(stoc) as stoc_sum FROM stocuri_mentor GROUP BY sku ) s ON c.nume_produs = s.sku AND WHERE stoc_sum >= c.qty the result is OK
EDIT 2 : SOLUTION = add 1 more condition WHERE stoc_sum >= c.qty AND ridicat <> 'Da'
You can try this query.
SELECT count(id) as orders_total, id_comanda, ridicat
FROM produse_com
WHERE ridicat != 'Da'
GROUP BY id_comanda;
Hello i have a query that selects products from a database, but for some reason it returns duplicates. The problem is in my joins i guess since in the product table there is no duplicate product. Here is my query:
$stmt=$dbh->prepare("SELECT
p.name,
p.slug,
p.id_product,
p.price,
pig.image,
c1.slug as ssubcat,
c2.slug as subcat,
c3.slug as cat
FROM
tbl_products p
INNER JOIN tbl_products_to_categories ptoc
ON ptoc.id_product = p.id_product
INNER JOIN tbl_catalog_categories c1
ON ptoc.id_category = c1.id_category
LEFT JOIN tbl_catalog_categories c2
ON c1.id_parent = c2.id_category
LEFT JOIN tbl_catalog_categories c3
ON c2.id_parent = c3.id_category
INNER JOIN tbl_products_images_gallery pig
ON pig.id_product = p.id_product
WHERE (c1.slug = :slug OR c2.slug = :slug OR c3.slug = :slug )
AND p.active = 1
AND p.quantity = 1
ORDER BY p.name ASC
LIMIT $start, $row_limit");
This is my query without variant options
SELECT p.*, pd.`name` AS `product_name`
FROM `product` AS `p`
LEFT JOIN `product_description` AS `pd` ON p.`id` = pd.`product_id`
LEFT JOIN `product_to_variant` AS `pv` ON p.`id` = pv.`product_id`
WHERE p.`status` = 0
GROUP BY p.`id`
ORDER BY p.`id` DESC;
SQLFiddle: http://sqlfiddle.com/#!9/8955b/5
and the follwing query has variant options but it doesn't work
SELECT p.*, pd.`name` AS `product_name`
FROM `product` AS `p`
LEFT JOIN `product_description` AS `pd` ON p.`id` = pd.`product_id`
LEFT JOIN `product_to_variant` AS `pv` ON p.`id` = pv.`product_id`
WHERE p.`status` = 0
AND (pv.`feature_id` = 2 AND pv.`variant_id` = 6)
AND (pv.`feature_id` = 3 AND pv.`variant_id` = 11)
GROUP BY p.`id`
ORDER BY p.`id` DESC;
and I also trying to query but there is no output
SELECT pv.* FROM `product_to_variant` AS `pv`
WHERE (pv.`feature_id` = 2 AND pv.`variant_id` = 2)
AND (pv.`feature_id` = 3 AND pv.`variant_id` = 11)
Do you have any other idea how to receive the products: 14, 15 by specific variant_id 6 AND 11 http://prntscr.com/ect2oh
Here is one method to do what you want:
SELECT p.*, pd.name AS product_name
FROM product p LEFT JOIN
product_description pd
ON p.id = pd.product_id JOIN
product_to_variant pv
ON p.id = pv.product_id
WHERE p.status = 0 AND
((pv.feature_id = 2 AND pv.variant_id = 6) OR
(pv.feature_id = 3 AND pv.variant_id = 11)
)
GROUP BY p.id
HAVING COUNT(DISTINCT feature_id) = 2
ORDER BY p.id DESC;
Notes:
No row can meet your original conditions. Because a column cannot have two values at the same time. Hence the OR rather than AND.
The HAVING clause checks that both values match.
There is no need for a LEFT JOIN to pv, because you are checking values from that table in the WHERE clause -- there have to be matches.
The LEFT JOIN to pa is probably also unnecessary.
Using backticks everywhere just makes the query harder to write and to read.
Maybe like this:
SELECT pv.* FROM `product_to_variant` AS `pv`
WHERE (pv.`feature_id` = 2 AND pv.`variant_id` = 2)
OR (pv.`feature_id` = 3 AND pv.`variant_id` = 11)
Instead of AND, which says, you need both feature_id and variant_id in the results, use OR because it takes both.
I have the following query which works... but I need some changes:
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints
FROM
golf_player p
LEFT JOIN
golf_card gC ON
p.pid = gC.pid
GROUP BY
p.pid
ORDER BY
p.name
DESC
What I really want is another property returned called totalleaguepoints which is a SUM of the most recent 20 league points in my table.
How do I add a limit to a group_concat?
It might be something like this?
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints,
SUM(
SELECT
gC2.leaguepoints
FROM
golf_card gC2
WHERE
gC2.pid = p.pid
ORDER BY
leaguepoints
DESC
LIMIT 20
) AS totalleaguepoints
FROM
golf_player p
LEFT JOIN
golf_card gC ON
p.pid = gC.pid
GROUP BY
p.pid
ORDER BY
p.name
DESC
P.S, the above query does not run
Do you want just the top 20 league points for each player in the group_concat as well as the sum?
If so maybe use user variables:-
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints,
SUM(gC.leaguepoints) AS totalleaguepoints
FROM golf_player p
LEFT JOIN
(
SELECT pid, leaguepoints, #Sequence:=IF(#PrevPid = pid, #Sequence + 1, 0) AS aSequence, #PrevPid := pid
FROM
(
SELECT pid, leaguepoints
FROM golf_card
ORDER BY pid, leaguepoints DESC
) Sub1
CROSS JOIN (SELECT #PrevPid := 0, #Sequence := 0) Sub2
) gC
ON p.pid = gC.pid AND aSequence < 20
GROUP BY p.pid
ORDER BY p.name DESC
How do i combine the counts from all the tables being used in a UNION query. This is what i have:
$query = "SELECT COUNT(*) as num
from table_one LEFT JOIN table_constant on table_one.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
UNION
SELECT COUNT(*) as num
from table_two LEFT JOIN table_constant on table_two.c_id
= table_constant.c_id
where table_two.added_by = '$uid'
UNION
SELECT COUNT(*) as num
from table_three LEFT JOIN table_constant ON table_three.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
UNION
SELECT COUNT(*) as num
from table_four LEFT JOIN table_constant ON table_four.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
ORDER BY date_time_added DESC";
$total_pages = mysql_fetch_array(mysql_query($query));
$total_pages = $total_pages[num];
Wrap the whole thing in yet another query and do the summation there.
SELECT sum(num)
FROM ( ... union queries here ...) as subquery;
Or loop over the returned rows in PHP and do the summation yourself.
Did you try to put count outside and apply it on sub query containing all tables union result.
SELECT COUNT(*) FROM (SELECT ...) as abc
Or try this out
Select mytable .userid, sum(mytable .subcount) as totalcount from
(
select userid, count(*) as subcount from table1 group by userid
union all
select userid, count(*) as subcount from table2 group by userid
)
as mytable
group by mytable .userid
or try using FULL OUTER JOIN instead of union it will give you the same result..
SELECT Count(UserID), UserId
FROM MyTable1
GROUP BY MyTable1.UserID
UNION
SELECT Count(UserID), UserId
FROM MyTable2
FULL OUTER JOIN MyTable2 ON (MyTable1.UserId=MyTable2.UserId)
GROUP BY MyTable2.UserID
Updated answer:
IF Your query is working fine follow my first option that i gave means
select count(*) from (your query) as pagecount..
Then your query would be like this.....
select count(*) from
(
SELECT COUNT(*) as num
from table_one LEFT JOIN table_constant on table_one.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
UNION
SELECT COUNT(*) as num
from table_two LEFT JOIN table_constant on table_two.c_id
= table_constant.c_id
where table_two.added_by = '$uid'
UNION
SELECT COUNT(*) as num
from table_three LEFT JOIN table_constant ON table_three.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
UNION
SELECT COUNT(*) as num
from table_four LEFT JOIN table_constant ON table_four.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
ORDER BY date_time_added DESC") as pagecount
There must be a better way to write that :/. A union is very powerful, but you are calling 4 selects in a single query, and if that is run every page, it will really hurt performance.
To answer you question, something like:
SELECT
SUM (mnTbl.num) as sumNum
FROM
(
SELECT
COUNT(*) as num
FROM
table_one
LEFT JOIN
table_constant
ON
table_one.c_id = table_constant.c_id
WHERE
table_constant.user_id = '$uid'
UNION
SELECT
COUNT(*) as num
FROM
table_two
LEFT JOIN
table_constant
ON
table_two.c_id = table_constant.c_id
WHERE
table_two.added_by = '$uid'
UNION
SELECT
COUNT(*) as num
FROM
table_three
LEFT JOIN
table_constant
ON
table_three.c_id = table_constant.c_id
WHERE
table_constant.user_id = '$uid'
UNION
SELECT
COUNT(*) as num
FROM
table_four
LEFT JOIN
table_constant
ON
table_four.c_id = table_constant.c_id
WHERE
table_constant.user_id = '$uid'
) as mnTbl
ORDER BY
date_time_added DESC