2017-02-12 44 views
1

以下查詢導致錯誤。派生表查詢不能在mysql中工作

select monstart, 
     sum(datediff(least(m.monend, t.end_date) + interval 1 day, 
        greatest(m.monstart, t.start_date) 
        ) 
      ) as days_worked 
from travel t join 
    (select date('2016-01-01') as monstart, date('2016-01-31') as monend union all 
     select date('2016-02-01') as monstart, date('2016-02-29') as monend union all 
select date('2016-03-01') as monstart, date('2016-03-31') as monend union all 
select date('2016-04-01') as monstart, date('2016-04-30') as monend union all 
select date('2016-05-01') as monstart, date('2016-05-31') as monend union all 
select date('2016-06-01') as monstart, date('2016-06-30') as monend union all 
select date('2016-07-01') as monstart, date('2016-07-31') as monend union all 
select date('2016-08-01') as monstart, date('2016-08-31') as monend union all 
select date('2016-09-01') as monstart, date('2016-09-30') as monend union all 
select date('2016-10-01') as monstart, date('2016-10-31') as monend union all 
select date('2016-11-01') as monstart, date('2016-11-30') as monend union all 
select date('2016-12-01') as monstart, date('2016-12-31') as monend union all 
    ) m 
    on t.end_date >= m.monstart and t.start_date <= m.monend 
group by m.monstart; 

錯誤如下。

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') m 
    on t.end_date >= m.monstart and t.start_date <= m.monend 
group by m.mon' at line 19 
+0

它看起來像一個頗爲曲折的查詢BTW – Strawberry

+0

你能解釋一下嗎?間接地, – DesirePRG

+0

。見http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple-sql-query – Strawberry

回答

3

您最後還有一個額外的union all。只要刪除它。

select monstart, 
     sum(datediff(least(m.monend, t.end_date) + interval 1 day, 
        greatest(m.monstart, t.start_date) 
        ) 
      ) as days_worked 
from travel t join 
    (select date('2016-01-01') as monstart, date('2016-01-31') as monend union all 
     select date('2016-02-01') as monstart, date('2016-02-29') as monend union all 
select date('2016-03-01') as monstart, date('2016-03-31') as monend union all 
select date('2016-04-01') as monstart, date('2016-04-30') as monend union all 
select date('2016-05-01') as monstart, date('2016-05-31') as monend union all 
select date('2016-06-01') as monstart, date('2016-06-30') as monend union all 
select date('2016-07-01') as monstart, date('2016-07-31') as monend union all 
select date('2016-08-01') as monstart, date('2016-08-31') as monend union all 
select date('2016-09-01') as monstart, date('2016-09-30') as monend union all 
select date('2016-10-01') as monstart, date('2016-10-31') as monend union all 
select date('2016-11-01') as monstart, date('2016-11-30') as monend union all 
select date('2016-12-01') as monstart, date('2016-12-31') as monend -- removed a union all from here 
    ) m 
    on t.end_date >= m.monstart and t.start_date <= m.monend 
group by m.monstart; 
1

你應該這樣做。如下:

select monstart, 
      sum(datediff(least(m.monend, t.end_date) + interval 1 day, 
         greatest(m.monstart, t.start_date) 
         ) 
       ) as days_worked 
    from travel t join 
     (select date('2016-01-01') as monstart, date('2016-01-31') as monend union all 
      select date('2016-02-01') as monstart, date('2016-02-29') as monend union all 
    select date('2016-03-01') as monstart, date('2016-03-31') as monend union all 
    select date('2016-04-01') as monstart, date('2016-04-30') as monend union all 
    select date('2016-05-01') as monstart, date('2016-05-31') as monend union all 
    select date('2016-06-01') as monstart, date('2016-06-30') as monend union all 
    select date('2016-07-01') as monstart, date('2016-07-31') as monend union all 
    select date('2016-08-01') as monstart, date('2016-08-31') as monend union all 
    select date('2016-09-01') as monstart, date('2016-09-30') as monend union all 
    select date('2016-10-01') as monstart, date('2016-10-31') as monend union all 
    select date('2016-11-01') as monstart, date('2016-11-30') as monend union all 
    select date('2016-12-01') as monstart, date('2016-12-31') as monend 
     ) m 
     on t.end_date >= m.monstart and t.start_date <= m.monend 
    group by m.monstart; 
1

您簡化查詢和像這樣的東西刪除加入僞表:不必更新查詢

select 
    sum(datediff(least(monend, end_date) + interval 1 day,greatest(monstart, start_date))) as `days_worked`, 
    (adddate(last_day(start_date), 1) - interval 1 month) as `monstart`, 
    last_day(start_date) as `monend` 
from travel 
group by `monstart`,`monend` 

這將在任何一年的工作。

編輯 - 試試這個:

select 
    (adddate(last_day(start_date), 1) - interval 1 month) as `monstart`, 
    last_day(start_date) as `monend`, 
    sum(
     datediff(
      least(last_day(start_date), end_date) + interval 1 day, 
      greatest((adddate(last_day(start_date), 1) - interval 1 month), start_date)) 
    ) as `days_worked` 
from travel 
group by `monstart`,`monend` 
+0

得到這個錯誤錯誤1054(42S22):'字段列表'中的未知列'm.monend' – DesirePRG

+0

我設法修復錯誤,您的查詢似乎是正確的。非常感謝 – DesirePRG

+0

對不起。我忘了刪除表別名。我已經更新了代碼示例。 –