Reputation: 6678
I have one huge project where I need to made statistics. This query give me accurate results but is a bit slow on loading and need somehow to optimize it but can't figure out how.
SELECT
TRIM(`op`.`products_quantity`) AS `products_quantity`,
TRIM(`op`.`products_price`) AS `products_price`,
TRIM(`op`.`orders_products_status`) AS `orders_products_status`,
TRIM(`p`.`product_type`) AS `product_type`,
IF(`p`.`product_type` IN ('G'),FLOOR(`op`.`final_price`*`op`.`products_quantity`),
`op`.`final_price`) AS `final_price`,
TRIM((
SELECT
`o`.`payment_method`
FROM
`orders` `o`
WHERE
`o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
)) AS `payment_method`,
IF(
TRIM(DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d/%m/%Y')) LIKE (
SELECT
TRIM(DATE_FORMAT(`o`.`date_purchased`,'%d/%m/%Y'))
FROM
`orders` `o`
WHERE
`o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
),
1,0
) AS `same_day`
FROM
`categories` `c`,
`categories_description` `cd`,
`products` `p`,
`orders_products` `op`
WHERE
`c`.`section_id` = 25
AND
`cd`.`categories_id` = `c`.`categories_id`
AND
`p`.`section_id` = `c`.`section_id`
AND
`p`.`product_type` IN ('P')
AND
`op`.`products_id` = `p`.`products_id`
GROUP BY `op`.`orders_products_id`
ORDER BY `payment_method` ASC
Do anyone have some suggestion?
I would like also some good explanation from SQL experts how is the best way to organize similar query and what need to be first inside WHERE
section.
Upvotes: 2
Views: 84
Reputation: 1402
As there is no data, I am not able to verify the query. But I think the following optional query may be helpful:
SELECT
TRIM(`op`.`products_quantity`) AS `products_quantity`,
TRIM(`op`.`products_price`) AS `products_price`,
TRIM(`op`.`orders_products_status`) AS `orders_products_status`,
TRIM(`p`.`product_type`) AS `product_type`,
IF(`p`.`product_type` = 'G', FLOOR(`op`.`final_price` * `op`.`products_quantity`), `op`.`final_price`) AS `final_price`,
TRIM(`t`.`payment_method`) AS `payment_method`,
IF( TRIM(DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d/%m/%Y')) LIKE
TRIM(DATE_FORMAT(`t`.`date_purchased`,'%d/%m/%Y')), 1, 0 ) AS `same_day`
FROM
`categories` `c` INNER JOIN `categories_description` `cd` ON `c`.`categories_id` = `cd`.`categories_id`
INNER JOIN `products` `p` ON `c`.`section_id` = `p`.`section_id`
INNER JOIN `orders_products` `op` ON `p`.`products_id` = `op`.`products_id`
INNER JOIN
( SELECT `o`.`orders_id`, `o`.`payment_method`,
TRIM(DATE_FORMAT(`o`.`date_purchased`,'%d/%m/%Y')) AS `date_purchased`
FROM `orders` `o` GROUP BY `o`.`orders_id` ) AS `t` ON `op`.`orders_id` = `t`.`orders_id`
WHERE `c`.`section_id` = 25 AND `p`.`product_type` IN ('P')
GROUP BY `op`.`orders_products_id`
ORDER BY `payment_method`;
Please note that following portion was common for both Inner sub-queries:
FROM `orders` `o`
WHERE `o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
Which means you are referring to the same table with same conditions twice, just to get two different columns. So I have removed that part and added it as INNER JOIN
of single sub-query.
Also note that there is only one value in bracket for both IN
. So I have replaced IN
by =
.
Please let me know if this is helpful to you.
Upvotes: 1
Reputation: 4904
You can do this more better way by Joining all tables by using JION
Try like this :-
SELECT
TRIM(`op`.`products_quantity`) AS `products_quantity`,
TRIM(`op`.`products_price`) AS `products_price`,
TRIM(`op`.`orders_products_status`) AS `orders_products_status`,
TRIM(`p`.`product_type`) AS `product_type`,
IF(`p`.`product_type` IN ('G'),FLOOR(`op`.`final_price`*`op`.`products_quantity`),
`op`.`final_price`) AS `final_price`,
TRIM((
SELECT
`o`.`payment_method`
FROM
`orders` `o`
WHERE
`o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
)) AS `payment_method`,
IF(
TRIM(DATE_FORMAT(STR_TO_DATE(`cd`.`concert_date`,'%d/%m/%Y'),'%d/%m/%Y')) LIKE (
SELECT
TRIM(DATE_FORMAT(`o`.`date_purchased`,'%d/%m/%Y'))
FROM
`orders` `o`
WHERE
`o`.`orders_id` = `op`.`orders_id`
GROUP BY `o`.`orders_id`
),
1,0
) AS `same_day`
FROM
`categories` `c`
join `categories_description` `cd` on `cd`.`categories_id` = `c`.`categories_id`
join `products` `p` on `p`.`section_id` = `c`.`section_id`
join `orders_products` `op` on `op`.`products_id` = `p`.`products_id`
WHERE
`c`.`section_id` = 25
AND
`p`.`product_type` IN ('P')
GROUP BY `op`.`orders_products_id`
ORDER BY `payment_method` ASC
Upvotes: 2
Reputation: 851
You can try and run few basic steps:
Upvotes: 1