I tried to select data where total greater than 3, but is not work, how to fix it?
SQL
SELECT p.image, p.id, p.name, sum(od.qty) AS total, sum(od.price * od.qty) AS nilai
FROM products p, order_details od, orders o
WHERE p.id = od.product_id
AND o.id = od.order_id
AND o.status = "Finished"
AND total > 6
GROUP BY p.id
ORDER BY nilai DESC
LIMIT 10
result
Total 6 still there. Any Advice?
Use having group by :
SELECT p.image, p.id, p.name, sum(od.qty) AS total, sum(od.price * od.qty) AS nilai
FROM products p, order_details od, orders o
WHERE p.id = od.product_id
AND o.id = od.order_id
AND o.status = "Finished"
GROUP BY p.id
HAVING sum(od.qty) > 3
ORDER BY nilai DESC
LIMIT 10
Related
I'm having trouble getting the total of most sold and total most viewed products correctly.
Case best sellers:
SELECT p.product_id, p.title, p.description, p.specifications, p.price, p.discount, p.discount_type, p.color, p.hours, p.product_type, p.gender, p.img, p.vdo_intro, p.status, p.url, p.date_start, p.date_end, p.ip, p.product_page, p.product_code, p.brand, p.color_url,
c.category_id, c.category_url as urlcategory, c.parent,
SUM(o.order_quantity) as solds
FROM order_detail o
JOIN product p ON o.product_id = p.product_id
JOIN category_relations rcat ON rcat.product_id = p.product_id
LEFT JOIN `category` c on rcat.category_id = c.category_id
WHERE p.gender = ? AND p.status=1 AND p.date_end IS NULL
GROUP BY p.product_id
ORDER BY SUM(o.order_quantity)
DESC LIMIT 12;
In Data Base i have:
id_order order_quantity order_price order_discount order_discount_type product_id order_date
1 2 59.00 0 % 1 2022-01-31 22:49:24
2 5 59.00 0 % 20 2022-01-31 22:49:24
3 12 59.00 0 % 8 2022-01-31 22:49:24
4 5 59.00 0 % 19 2022-01-31 22:49:24
5 25 59.00 0 % 17 2022-01-31 22:49:24
6 3 59.00 0 % 1 2022-01-31 22:49:24
Result i get :
id:1 2 + 3 = 5 solds i get = 20 solds (wrong).
id:20 5 solds i get = 15 solds (wrong).
id:8 12 solds i get = 36 solds (wrong).
id:19 5 solds i get = 5 solds (ok).
id:17 25 solds i get = 50 solds (wrong).
Does anyone know what I'm doing wrong?
It look like that it is multiplying the results by records.
Case most visits:
SELECT p.product_id, p.title, p.description, p.specifications, p.price, p.discount, p.discount_type, p.color, p.hours, p.product_type, p.gender, p.img, p.vdo_intro, p.status, p.url, p.date_start, p.date_end, p.ip, p.product_page, p.product_code, p.brand, p.color_url,
c.category_id, c.category_url as urlcategory, c.parent,
SUM(v.total) as visits
FROM `visits` v
JOIN `product` p ON v.product_id = p.product_id
JOIN category_relations rcat ON rcat.product_id = p.product_id
LEFT JOIN `category` c on rcat.category_id = c.category_id
WHERE p.gender = ? AND p.status=1 AND p.date_end IS NULL
GROUP BY p.product_id
ORDER BY SUM(v.total)
DESC LIMIT 12
My database:
id_visits total ip today product_id
23 5 xxxxxxxxxxxxx1 2022-02-09 1
36 1 xxxxxxxxxxxxx4 2022-02-06 13
40 1 xxxxxxxxxxxxx3 2022-02-06 13
41 1 xxxxxxxxxxxxx1 2022-02-06 21
48 1 xxxxxxxxxxxxx2 2022-02-07 13
50 1 xxxxxxxxxxxxx2 2022-02-07 1
62 1 xxxxxxxxxxxxx8 2022-02-08 1
Result i get:
id1 : 5 + 1 + 1 = 7 visits i get 28 visits (wrong)
id13: 1 + 1 + 1 = 3 visits i get 9 visits (wrong)
id21: 1 = 1 visits i get 3 visits (wrong)
Does anyone know the error, because it does not add up correctly?
note: I can add the tables if needed
Edit:
DB Fiddle
If i do:
GROUP BY rcat.cat_relation_id
I get the calculation right, but it repeats the same products
Your problem is that category_relations is a many to many table. So when you join it you get additional results for each category that a product is in. So product id1 is in 4 categories so you get a sum of 28 instead of 7.
Your query is producing a row for each order for each category that the product ordered is in and then grouping all rows with the same product_id together. SUM will add all the values from all the rows grouped together.
If you want one line per product you need to group by product_id. You could remove the category data (3 items in SELECT and 2 JOINS), but if you need that category data in that one line per product you need to aggregate the category data with an aggregate function such as GROUP_CONCAT(). Then you can fix the sum by dividing by the number of categories. You can get the number of categories with COUNT(DISTINCT category_id).
Your queries would look like this:
SELECT
p.product_id,
p.title,
p.description,
p.specifications,
p.price,
p.discount,
p.discount_type,
p.color,
p.hours,
p.product_type,
p.gender,
p.img,
p.vdo_intro,
p.status,
p.url,
p.date_start,
p.date_end,
p.ip,
p.product_page,
p.product_code,
p.brand,
p.color_url,
GROUP_CONCAT(DISTINCT c.category_id) AS category_id,
GROUP_CONCAT(DISTINCT c.category_url) AS urlcategory,
GROUP_CONCAT(DISTINCT c.parent) AS parent,
ROUND(SUM(o.order_quantity) / COUNT(DISTINCT c.category_id)) AS solds
FROM order_detail o
JOIN product AS p ON o.product_id = p.product_id
JOIN category_relations rcat ON rcat.product_id = p.product_id
LEFT JOIN category AS c ON rcat.category_id = c.category_id
WHERE
p.gender = ? AND
p.status=1 AND
p.date_end IS NULL
GROUP BY p.product_id
ORDER BY ROUND(SUM(o.order_quantity) / COUNT(DISTINCT c.category_id)) DESC
LIMIT 12;
SELECT
p.product_id,
p.title,
p.description,
p.specifications,
p.price,
p.discount,
p.discount_type,
p.color,
p.hours,
p.product_type,
p.gender,
p.img,
p.vdo_intro,
p.status,
p.url,
p.date_start,
p.date_end,
p.ip,
p.product_page,
p.product_code,
p.brand,
p.color_url,
GROUP_CONCAT(DISTINCT c.category_id) AS category_id,
GROUP_CONCAT(DISTINCT c.category_url) AS urlcategory,
GROUP_CONCAT(DISTINCT c.parent) AS parent,
ROUND(SUM(v.total) / COUNT(DISTINCT c.category_id)) AS solds
FROM
visits AS v
JOIN product AS p ON v.product_id = p.product_id
JOIN category_relations AS rcat ON rcat.product_id = p.product_id
LEFT JOIN category AS c ON rcat.category_id = c.category_id
WHERE
p.gender = ? AND
p.status=1 AND
p.date_end IS NULL
GROUP BY p.product_id
ORDER BY ROUND(SUM(v.total) / COUNT(DISTINCT c.category_id))
DESC LIMIT 12;
DB Fiddle
(I commented some stuff in the fiddle to make it easier to see the results)
To have a consistent order for the category fields that were concatenated you can use an ORER BY clause in the GROUP CONCAT function:
GROUP_CONCAT(DISTINCT c.category_id ORDER BY c.category_id) AS category_id,
GROUP_CONCAT(DISTINCT c.category_url ORDER BY c.category_id) AS urlcategory,
GROUP_CONCAT(DISTINCT c.parent ORDER BY c.category_id) AS parent,
MySQL doc for GROUP_CONCAT
If you only need one result from categories, let's say the category with the lowest id, you can use this trick: You left join your category_relations again with a condition that category_id is lower than the first one and then in your WHERE clause only select the rows where that IS NULL - no lower category_id was found.
...
c.category_id,
c.category_url,
c.parent,
ROUND(SUM(o.order_quantity) / COUNT(DISTINCT c.category_id)) AS solds
FROM order_detail o
JOIN product AS p ON o.product_id = p.product_id
JOIN category_relations rcat ON rcat.product_id = p.product_id
LEFT JOIN category AS c ON rcat.category_id = c.category_id
LEFT JOIN category_relations AS rcat2 ON rcat.product_id = p.product_id AND rcat2.category_id < rcat.category_id
WHERE
p.gender = ? AND
p.status=1 AND
p.date_end IS NULL AND
rcat2.category_id IS NULL
GROUP BY p.product_id, c.category_id
ORDER BY ROUND(SUM(o.order_quantity) / COUNT(DISTINCT c.category_id)) DESC
...
I have tables named company, product, purchase_order, skid, process_record and I want MySQL query result as below.
I tried
SELECT s.id as skidId, s.skidBarcode, po.poNumber, s.companyId, c.companyName, p.productId , p.productName, totalProcessed
FROM skid s
INNER JOIN company c ON s.companyId = c.id
INNER JOIN purchase_order po on s.purchaseOrderId = po.id
INNER JOIN product prdct on p.productId = prdct.id
LEFT JOIN (SELECT skidID, productId , COUNT(*) as processedQuantity FROM process_record GROUP BY productId ) p ON p.skidID= s.id
WHERE s.status = 'closed' ORDER By s.companyId,s.id
However, this query result gives processedQuantity count NULL and random wrong count on some rows.
How can I get the desired MySQL query output as shown in screenshot?
I added GROUP BY skidID, productId instead of GROUP BY productId and it resolved the issue.
SELECT s.id as skidId, s.skidBarcode, po.poNumber, s.companyId, c.companyName, p.productId , p.productName, totalProcessed
FROM skid s
LEFT JOIN (SELECT skidID, productId , COUNT(*) as processedQuantity FROM process_record GROUP BY skidID, productId ) p ON p.skidID= s.id
INNER JOIN company c ON s.companyId = c.id
INNER JOIN purchase_order po on s.purchaseOrderId = po.id
INNER JOIN product prdct on p.productId = prdct.id
WHERE s.status = 'closed' ORDER By s.companyId,s.id
I have reports table that aggregates data each product quantity each day.
SELECT r.year, r.month, c.id, c.client_name, p.product_name, cc.country_name, sum(r.quantity) units FROM
client c
join report r on c.id = r.client_id
join product p on r.product_id = p.id
join country cc on r.country_id = c.id
WHERE r.year = year(now())
group by r.year, r.month, c.id, p.product_name, cc.country_name
I'm trying to figure out how group units sum by month, client, product and country where query shows sum for top 5 countries and rest is sum from bottom countries. Something like this:
case
when sum(r.quantity) = 'Top 1' then cc.country_name
when sum(r.quantity) = Top 2' then cc.country_name
.....
when sum(r.quantity) = 'Top 2' then cc.country_name
else 'Other'
How can I do this?
Many thanks in advance
you can try this. Here i sort the result from most quantity to less and add a row number. so the first 6 are the top.
please try it, but i cant tested.
SELECT
#nr := ( #nr +1) AS nr,
IF ( #nr < 7, CONCAT('Top ',#nr), 'other' ) AS top,
r.* FROM (
SELECT r.year, r.month, c.id, c.client_name, p.product_name, cc.country_name, sum(r.quantity) units
FROM CLIENT c
JOIN report r ON c.id = r.client_id
JOIN product p ON r.product_id = p.id
JOIN country cc ON r.country_id = c.id
WHERE r.year = YEAR(now())
GROUP BY r.year, r.month, c.id, p.product_name, cc.country_name
ORDER BY sum(r.quantity) DESC
) AS r
CROSS JOIN ( SELECT #nr:=0 ) AS params;
I want to LIMIT timber orders query to 10 for pagination. The problem i'm having is the LEFT JOIN timber_order_products is counted with the LIMIT. The LIMIT should only apply to timber_orders.
$data = $DB2->query("
SELECT o.order_id
, o.order_status
, o.customer_method
, o.payment_method
, o.customer_notes
, o.order_date
, p.name product_name
, p.price product_price
FROM timber_orders o
LEFT
JOIN timber_order_products p
ON p.order_id = o.order_id
ORDER
BY order_id DESC
LIMIT 10
");
How do i LIMIT results only from a specific table? The LIMIT 10 should only apply to timber_orders. I can't group by because i need the timber_order_products rows.
You can use a subquery:
SELECT o.order_id , o.order_status, o.customer_method, o.payment_method,
o.customer_notes, o.order_date,
p.name as product_name, p.price as product_price
FROM (select o.*
from timber_orders o
order by order_id desc
limit 10
) o LEFT JOIN
timber_order_products p
on p.order_id = o.order_id
ORDER BY o.order_id DESC
LIMIT 10
Avoiding using a sub query, I would use GROUP_CONCAT. Then the products name and price can be split off in the code that displays the data:-
SELECT o.order_id
, o.order_status
, o.customer_method
, o.payment_method
, o.customer_notes
, o.order_date
, GROUP_CONCAT(CONCAT_WS('~', p.name, p.price)) AS product_name_price
FROM timber_orders o
LEFT OUTER JOIN timber_order_products p
ON p.order_id = o.order_id
GROUP BY o.order_id
, o.order_status
, o.customer_method
, o.payment_method
, o.customer_notes
, o.order_date
ORDER BY order_id DESC
LIMIT 10
select sum(price)
from product
where id in (select productid
from orders where status!=0
and userid=1)
if my returned productid = (1,2,2)
the sum will only be sum of 1 and 2 instead of sum of 1,2,and2
i tried
select sum(price) from product where id in (1,2,2)
same result, how do i get indistinct sum?
SELECT SUM(p.price)
FROM product AS p
LEFT JOIN orders AS o
ON p.id = o.productid
WHERE o.productid IS NOT NULL
AND o.status <> 0
AND o.userid = 1