开发者

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')
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜