Optimizing MySQL query for fetching data using time range
I'm building a line chart for a product sales report by using the Google Chart API and are separating the data on a per day basis with basically running the same query in a loop for each day using UNION ALL as glue.
E.g. A report for a whole year will repeat the query, using UNION ALL 365 times.
I'm guessing this is not a -best practice- example so if anyone would be so kind and point me in the right direction of how to optimize this query, I would greatly appreciate it.
SELECT SUM(op.qty) AS qty
FROM uc_order_products op
LEFT JOIN uc_orders o ON o.order_id = op.order_id
LEFT JOIN node n ON n.nid = op.nid
LEFT JOIN node_type nt ON nt.type = n.type
WHERE (o.created > 1247695200) AND (o.created < 1247781600)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
UNION ALL
SELECT SUM(op开发者_运维知识库.qty) AS qty
FROM uc_order_products op
LEFT JOIN uc_orders o ON o.order_id = op.order_id
LEFT JOIN node n ON n.nid = op.nid
LEFT JOIN node_type nt ON nt.type = n.type
WHERE (o.created > 1247781600) AND (o.created < 1247868000)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
UNION ALL
SELECT SUM(.......
Thanks for all the quick replies! With the query example from jspcal, my query ended up like this:
SELECT SUM(op.qty) AS qty, DATE_FORMAT(FROM_UNIXTIME(o.created),'%d-%m-%Y') AS day
FROM uc_order_products op
LEFT JOIN uc_orders o ON o.order_id = op.order_id
LEFT JOIN node n ON n.nid = op.nid
LEFT JOIN node_type nt ON nt.type = n.type
WHERE (o.created > 1247695200) AND (o.created < 1263596400)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
GROUP BY day
And with PHP, I combine a complete date range array (matching array keys with strtotime($data->day)
from the query result) to get days with no sale.
you can group by day:
select sum(op.qty) as qty, date_format(o.created, '%Y-%m-%d') as day
from ... where ... o.created >= subdate(now(), interval 1 year) and
o.created <= now() group by day order by day
will report the sum for each day of the year in the data set
You sould be able to convert
WHERE (o.created > 1247695200) AND (o.created < 1247781600)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
WHERE (o.created > 1247781600) AND (o.created < 1247868000)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
....
To something like
WHERE (
(o.created > 1247695200) AND (o.created < 1247781600)
OR (o.created > 1247781600) AND (o.created < 1247868000)
...
)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
精彩评论