2012-01-18 9 views
1

データの中断が発生した日数を選択する必要があります。mysqlは、前日の行が存在しない日付を検索します。

表形式:

id (autoincrement), user_id (int), start (datetime), end (datetime) 

例データ(時間は日のみを必要とするようにして左):

1, 5, 2011-12-18, 2011-12-18 
2, 5, 2011-12-17, 2011-12-17 
3, 5, 2011-12-16, 2011-12-16 
4, 5, 2011-12-13, 2011-12-13 

をあなたは2011-間に休憩があるだろう見ることができるように表示するように簡単にそれをです12-13および2011-12-16。

日2011年12月18日を使用して、ブレークまでありますどのように多くの日数::おそらく

2011-12-18: Lowest sequential date = 2011-12-16: Total consecutive days: 3 

:今、私はできると言うする必要がDATE_DIFF(2011-12-18, 2011-12-16)だから私の問題がある

、 2011-12-16が最も低い連続日であることを選択するにはどうすればよいですか?データは特定のuser_idのものに当てはまることを思い出してください。

ここの例のようになります。逆の場合はhttp://www.artfulsoftware.com/infotree/queries.php#72です。マックスが出finededすることができますので、左は、シーケンスにすることができ1つの日付を選択して参加する -

は、私は、これはSQLでのみ、ノーPHPコード

おかげ

+0

MySQLだけでなく、PHP/ASP/JSPなどを使用していますか?おそらく、スクリプトレベルでのギャップを「キャッチ」するのが最も簡単でしょう。 – Oldskool

+0

理想的にはスピードの目的でmysqlのみを使用したい - ヒープを経由して行のヒープを調べるだけで、nullを見つけることは自分のデータにとって効率的ではない – Ashley

答えて

0
SELECT qmin.start, qmax.end, DATE_DIFF(qmax.end, qmin.start) FROM table AS qmin 
    LEFT JOIN ( 
    SELECT end FROM table AS t1 
     LEFT JOIN table AS t2 ON 
     t2.start > t1.end AND 
     t2.start < DATE_ADD(t1.end, 1 DAY) 
     WHERE t1.end >= '2011-12-18' AND t2.start IS NULL 
     ORDER BY end ASC LIMIT 1 
) AS qmax 
    LEFT JOIN table AS t2 ON 
    t2.end < qmin.start AND 
    t2.end > DATE_DIFF(qmin.start, 1 DAY) 
    WHERE qmin.start <= '2011-12-18' AND t2.start IS NULL 
    ORDER BY end DESC LIMIT 1 

これは動作するはずが行わたい連続レコードなしで最も近いレコードを取った場合(t2.anyfieldがnull)、最小限の日付で行うのと同じことです。

スクリプト内の間の日を計算することができた場合 - それはあなたのような何か試すことが、その後の美しさの内容はない場合 - (最小限の、2行の最大例えば1行)

0

それが労働組合を使用して行います。

select t.start, t2.start, datediff(t2.start, t.start) + 1 as consecutive_days 
from tab t 
join tab t2 on t2.start = (select min(start) from (
     select c1.*, case when c2.id is null then 1 else 0 end as gap 
     from tab c1 
     left join tab c2 on c1.start = adddate(c2.start, -1) 
    ) t4 where t4.start <= t.start and t4.start >= (select max(start) from (
     select c1.*, case when c2.id is null then 1 else 0 end as gap 
     from tab c1 
     left join tab c2 on c1.start = adddate(c2.start, -1) 
    ) t3 where t3.start <= t.start and t3.gap = 1)) 
where t.start = '2011-12-18' 

結果は次のようになります。

start  start  consecutive_days 
2011-12-18 2011-12-16 3 
0

チェックこれを、

SELECT DATEDIFF((SELECT MAX(`start`) FROM testtbl WHERE `user_id`=1), 
(select a.`start` from testtbl as a 
left outer join testtbl as b on a.user_id = b.user_id 
AND a.`start` = b.`start` + INTERVAL 1 DAY 
where a.user_id=1 AND b.`start` is null 
ORDER BY a.`start` desc LIMIT 1)) 

DATEDIFF()は、2日間の差異を表示します。連続する日数をその結果に加算する場合は、