在范围之间添加每月预订天数

时间:2015-03-16 19:13:08

标签: mysql

我正在计算

  1. 每月预订的天数(自第一条记录以来的每个月)
  2. 总价格基于总天数和费率。

    INSERT INTO `reservations`
    (`id`, `user_id`, `property_id`,     `actual_check_in`,`actual_check_out`)
    VALUES
    (5148, 1,  2, '2014-01-01', '2014-01-10'),
    (5149, 1,  2, '2014-02-03', '2014-02-10'),
    (5151, 1,  2, '2014-02-02', '2014-02-15'),
    (5153, 1,  2, '2014-03-05', '2014-03-10'),
    (5153, 1,  2, '2014-02-20', '2014-03-30'),
    
    
    
    
    
    SELECT 
     YEAR(month.d),
     MONTHNAME(month.d),
     r.property_id,
     SUM(
        DATEDIFF(LEAST(actual_check_out, LAST_DAY(month.d)), GREATEST(actual_check_in, month.d))
     ) AS days,
     SUM(days*p.rate),
    MIN(r.actual_check_in) as firstDate,
    MAX(r.actual_check_out) as lastDate
    FROM reservations as r
    LEFT JOIN property as p on r.property_id=p.id
    RIGHT JOIN (
              select
              DATE_FORMAT(m1, '%Y%m%d') as d
              from
              (
              select 
              (firstDate - INTERVAL DAYOFMONTH(firstDate)-1 DAY) 
              +INTERVAL m MONTH as m1
              from
              (
              select @rownum:=@rownum+1 as m from
              (select 1 union select 2 union select 3 union select 4) t1,
              (select 1 union select 2 union select 3 union select 4) t2,
              (select 1 union select 2 union select 3 union select 4) t3,
              (select 1 union select 2 union select 3 union select 4) t4,
              (select @rownum:=-1) t0
              ) d1
              ) d2 
              where m1<=lastDate
              order by m1
         )      AS month ON
         actual_check_in <= LAST_DAY(month.d)
     AND month.d <= actual_check_out
     GROUP BY user_id, month.d 
    
  3. 麻烦我有:

    1. 让MySQL接受firstDate&amp;的变量加入查询中的lastDate
    2. 我想在同一个月将同一用户预订的每月天数相加。我试图将正确的部分转换为子查询来计算但是遇到了麻烦......
    3. http://sqlfiddle.com/#!9/71e34/1

      我希望得到的结果(如果房产费率是150 /天):

      DATE     |  USER  |  #Days  |  Total Rate
      --------------------------------------
      01/2014  |  1     |   9     | 1350
      01/2014  |  2     |   0     | 0
      02/2014  |  1     |   30    | 4500
      02/2014  |  2     |   0     | 0
      03/2014  |  1     |   35    | 5250
      03/2014  |  2     |   0     | 0
      04/2014  |  1     |   0     | 0
      04/2014  |  2     |   0     | 0
      

      *#天数可能超过一个月中的天数,因为该月可能存在多个预订

      更新----这几乎解决了这个问题,但我在第二个大选择语句中遇到了麻烦,无法正确计算价格。查询仅考虑第一个属性率,而不是根据连接语句选择它们。有什么帮助吗?

      select 
           r.user_id,
          DATE_FORMAT(m1, '%b %Y') as date,
          (SELECT 
              SUM( 
                  DATEDIFF(LEAST(actual_check_out, LAST_DAY(m1)), GREATEST(actual_check_in, m1))
                  ) AS numdays
             FROM reservations 
              where actual_check_in <= LAST_DAY(m1)
                       AND m1 <= actual_check_out
                       AND user_id=r.user_id
              GROUP BY  m1) as days,
      
          (SELECT 
              SUM( 
                  DATEDIFF(LEAST(r.actual_check_out, LAST_DAY(m1)), GREATEST(r.actual_check_in, m1))
                  ) *p.rate  
             FROM reservations  as r
           left join property as p
           on r.property_id=p.id
              where actual_check_in <= LAST_DAY(m1)
                       AND m1 <= actual_check_out
                       AND user_id=r.user_id
              GROUP BY  m1) as price
      
          from (
      
          select ('2015-01-01' - INTERVAL DAYOFMONTH('2015-01-01')-1 DAY) +INTERVAL m MONTH as m1 from (
              select @rownum:=@rownum+1 as m from
                  (select 1 union select 2 union select 3 union select 4) t1,
                  (select 1 union select 2 union select 3 union select 4) t2,
                  (select 1 union select 2 union select 3 union select 4) t3,
                  (select 1 union select 2 union select 3 union select 4) t4,
                  (select @rownum:=-1) t0
              ) d1
          ) d2 
            cross join reservations as r
      where m1<=CURDATE() group by user_id, m1 order by m1
      

      http://sqlfiddle.com/#!9/36035/21

2 个答案:

答案 0 :(得分:0)

仍然不确定您的请求,但下面的查询可能会指向您正确的方向:

SELECT DATE_FORMAT(r.actual_check_in, '%m/%Y') AS mnth, r.user_id,
DATEDIFF(MAX(r.actual_check_out),MIN(r.actual_check_in)) AS days,
DATEDIFF(MAX(r.actual_check_out),MIN(r.actual_check_in))*p.rate AS totalRate
FROM reservations r
JOIN property p ON r.property_id=p.id
GROUP BY DATE_FORMAT(r.actual_check_in, '%m/%Y'), r.user_id;

返回如下数据:

mnth     user_id    days  totalRate  
-------  -------  ------  -----------
01/2014        1       9         1350
02/2014        1      56         8400
03/2014        1       5          750

答案 1 :(得分:0)

http://sqlfiddle.com/#!9/36035/36

     select 
     r.user_id as userId,
    DATE_FORMAT(m1, '%b %Y') as date,
    (SELECT 
        SUM( 
            DATEDIFF(LEAST(actual_check_out, LAST_DAY(m1)), GREATEST(actual_check_in, m1))
            ) AS numdays
       FROM reservations 
        where actual_check_in <= LAST_DAY(m1)
                 AND m1 <= actual_check_out
                 AND user_id=userId
        GROUP BY  m1) as days,

    (SELECT 

            sum(DATEDIFF(LEAST(r.actual_check_out, LAST_DAY(m1)), GREATEST(r.actual_check_in, m1))*p.rate)

       FROM reservations  as r
      left join property as p
     on r.property_id=p.id
        where r.actual_check_in <= LAST_DAY(m1)
                 AND m1 <= r.actual_check_out
                 AND r.user_id=userId
        GROUP BY  m1) as price

    from (

    select ('2015-01-01' - INTERVAL DAYOFMONTH('2015-01-01')-1 DAY) +INTERVAL m MONTH as m1 from (
        select @rownum:=@rownum+1 as m from
            (select 1 union select 2 union select 3 union select 4) t1,
            (select 1 union select 2 union select 3 union select 4) t2,
            (select 1 union select 2 union select 3 union select 4) t3,
            (select 1 union select 2 union select 3 union select 4) t4,
            (select @rownum:=-1) t0
        ) d1
    ) d2 
      cross join reservations as r
where m1<=CURDATE() group by user_id, m1 order by m1