mysql日报告查询

时间:2011-02-22 18:33:29

标签: mysql

以下查询为我提供了一份针对设备租赁公司的项目报告。这是一个超级复杂的查询,需要大约20秒才能运行。这显然不是获取我正在寻找的数据的正确方法。我从PHP构建此查询并添加开始日期02-01-2011和结束日期03-01-2011,产品代码(p_code = 1)和产品池(i_pool = 1)。这4条信息被传递给PHP函数并注入到以下sql中,以返回我需要的日历控件所需的报告,显示有多少项。我的问题是:有没有办法简化或做得更好,或运行更有效,使用更好的连接或更好的方式来显示个别日子。

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 SELECT 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

如果还有其他需要的信息,请告诉我,我会发布。

3 个答案:

答案 0 :(得分:1)

您可以使用:

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

我不确定你是否需要这个或其他东西。

  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

答案 1 :(得分:0)

找到所有日子:

SELECT DATE(IFNULL(ri_delivery,ri_pickup))AS date FROM rental_inv AS dateindex WHERE [YEAR-MONTH-1]&lt; = ri_delivery&lt; = LAST_DAY([YEAR-MONTH-1])或[ YEAR-MONTH-1]&lt; = ri_pickup&lt; = LAST_DAY([YEAR-MONTH-1])GROUP BY date没有ISNULL(date

找出项目

SELECT COUNT(id)FROM rental_inv WHERE ri_pickup = [DATE]; 在

中查找项目

SELECT COUNT(id)FROM rental_inv WHERE ri_delivery = [DATE]; 找到平衡

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]或in.ri_delivery = [DATE]

您可能可以加入所有内容,但由于其程序更加清晰;

答案 2 :(得分:0)

我不确定这是否是你问题的确切答案,但我想我会这样做。 (我没有使用任何SQL编辑器,所以你需要检查语法我猜)

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