开发者

mysql day report query

The query below gives me a report of items that are out for an equipment rental company. this is a super complicated query that takes almost 20 seconds to run. This is obviously not the correct way to get the data that I'm looking for. I build this query from PHP and add in the start date of 02-01-2011 and the end date of 03-01-2011, the product code (p_code = 1) and product pool (i_pool =1). Those 4 pieces of information are passed to a PHP function and injected into the following sql to return the report I need for a calendar control displaying how many items are out. My question is: Is there any way to simplify or do this better, or run more efficiently, using better joins or a better way to display the individual days.

SELECT   DISTINCT reportdays.reportday, count(*)
FROM 
(SELECT '2011-02-01' + INTERVAL a + b DAY reportday
FROM
 (SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3
    UNION SELECT 4 UNION SELECT 5 UNION S开发者_如何学GoELECT 6 UNION SELECT 7
    UNION SELECT 8 UNION SELECT 9 ) d,
 (SELECT 0 b UNION SELECT 10 UNION SELECT 20 
    UNION SELECT 30 UNION SELECT 40) m 
WHERE '2011-02-01' + INTERVAL a + b DAY  <  '2011-03-01'
ORDER BY a + b) as reportdays
 JOIN rental_inv as line 
    ON DATE(FROM_UNIXTIME(line.ri_delivery_dte)) <= reportdays.reportday
  AND  DATE(FROM_UNIXTIME(line.ri_pickup_dte)) >= reportdays.reportday
 LEFT OUTER JOIN rental_in as rent on line.ri_num = rent.ri_num
 LEFT OUTER JOIN rental_cancels cancelled on rent.ri_num = cancelled.ri_num
 LEFT OUTER JOIN inv inventory on line.i_num = inventory.i_num
 LEFT OUTER JOIN product ON inventory.p_code = product.p_code
 WHERE rent.ri_extend = 0      -- disregard extended rentals
  AND cancelled.ri_num is null -- disregard cancelled rentals
  AND inventory.p_code = 1
  AND inventory.i_pool = 1

 GROUP BY reportdays.reportday

If there is any other information needed, let me know and I'll post it.


You can use:

SELECT DATE(ri_delivery) as day,
       count(*) as itemsout,
  FROM rental_inv
GROUP BY day;

I'm not sure if you need this or a different thing.

  SELECT dates.day, count (*)
    FROM rental_inv line
         INNER JOIN (SELECT DATE(ri_delivery_dte) as day FROM rental_inv  
                      WHERE ri_delivery_dte >= '2011/02/01' 
                        AND ri_delivery_dte <= '2011/02/28' 
                     GROUP BY day
                     UNION 
                     SELECT DATE(ri_pickup_dte) as day FROM rental_inv 
                      WHERE ri_pickup_dte >= '2011/02/01' 
                        AND ri_pickup_dte <= '2011/02/28'
                    GROUP BY day) dates
                 ON line.ri_delivery_dte <= dates.day and line.ri_pickup_dte >= dates.day
          LEFT JOIN rental_cancels canc on line.ri_num =  canc.ri_num 
          LEFT JOIN rental_in rent on line.ri_num = rent.ri_num
    WHERE  canc.ri_num is  null
       AND rent.ri_extend = 0
 GROUP BY dates.day


to find all days:

SELECT DATE(IFNULL(ri_delivery,ri_pickup)) AS date FROM rental_inv AS dateindex WHERE [YEAR-MONTH-1] <= ri_delivery <= LAST_DAY([YEAR-MONTH-1]) OR [YEAR-MONTH-1] <= ri_pickup <= LAST_DAY([YEAR-MONTH-1]) GROUP BY date HAVING NOT ISNULL(date)

to find items out

SELECT COUNT(id) FROM rental_inv WHERE ri_pickup = [DATE]; to find items in

SELECT COUNT(id) FROM rental_inv WHERE ri_delivery = [DATE]; to find balance

SELECT COUNT(out.id) - COUNT(in.id) FROM rental_inv AS out INNER JOIN rental_inv AS in ON DATE(out.ri_pickup) = DATE(in.ri_delivery) WHERE out.ri_pickup = [DATE] OR in.ri_delivery = [DATE]

You probably can join up everything but since its procedure its more clear;


I am not sure if this would be the exact answer to your problem but I would do something like this I guess. (I didn't use any SQL editor so u need to check syntax I guess)

SELECT 
    reportdays.d3 as d, 
    ( COALESCE(outgoing.c1,0) - COALESCE(incoming.c2,0) ) as c
FROM
-- get report dates 
(
    SELECT DATE(FROM_UNIXTIME(COALESCE(l3.ri_delivery_dte, l3.ri_pickup_dte)) d3
    FROM rental_inv l3
    WHERE
        (l3.ri_delivery_dte >= UNIX_TIMESTAMP('2011-02-01') 
            AND l3.ri_delivery_dte < UNIX_TIMESTAMP('2011-03-01'))
        OR (l3.ri_pickup_dte >= UNIX_TIMESTAMP('2011-02-01') 
            AND l3.ri_pickup_dte < UNIX_TIMESTAMP('2011-03-01'))
    GROUP BY d3
) as reportdays
-- get outgoing
LEFT JOIN ( 
    SELECT DATE(FROM_UNIXTIME(l1.ri_delivery_dte)) as d1, count(*) as c1
    FROM rental_inv l1
    LEFT JOIN rental_cancels canc1 on l.ri_num =  canc1.ri_num 
    LEFT JOIN rental_in rent1 on l.ri_num = rent1.ri_num
    WHERE
       l1.ri_delivery_dte >= UNIX_TIMESTAMP('2011-02-01')
       AND l1.ri_delivery_dte < UNIX_TIMESTAMP('2011-03-01')
       AND  canc1.ri_num is  null
       AND rent1.ri_extend = 0
    GROUP BY d1
) as outgoing ON reportdays.d3 = outgoing.d1
-- get incoming
LEFT JOIN ( 
    SELECT DATE(FROM_UNIXTIME(l2.ri_pickup_dte)) as d2, count(*) as c2
    FROM rental_inv l2
    LEFT JOIN rental_cancels canc2 on l2.ri_num =  canc2.ri_num 
    LEFT JOIN rental_in rent2 on l2.ri_num = rent2.ri_num
    WHERE
       l2.ri_pickup_dte >= UNIX_TIMESTAMP('2011-02-01')
       AND l2.ri_pickup_dte < UNIX_TIMESTAMP('2011-03-01')
       AND  canc2.ri_num is  null
       AND rent2.ri_extend = 0
    GROUP BY d2
) as incoming ON reportdays.d3 = incoming.d2
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜