あなたがPreferred、date_from、date_toという列を持つテーブルを持っていて、あなたはただの数を計算しようとしていると仮定します。
このクエリを試すことができます。
SET @checkin = '2016-01-16';
SET @checkout = '2016-02-08';
SELECT T0.preferred,T0.date_from,T0.date_to,IFNULL(NIGHTS.nights,0) as Nights
FROM YourTable T0
LEFT JOIN
(SELECT T1.preferred,T1.date_from,T1.date_to,COUNT(*) AS Nights
FROM YourTable AS T1
INNER JOIN
(SELECT (@checkin + INTERVAL n DAY) as singleday
FROM numbers
WHERE (@checkin + INTERVAL n DAY) <= @checkout)DAYS1
ON DAYS1.singleday BETWEEN T1.date_from AND T1.date_to
WHERE T1.preferred = 1
OR NOT EXISTS
(SELECT 1
FROM YourTable AS T
WHERE T.preferred = 1
AND DAYS1.singleday BETWEEN T.date_from AND T.date_to
)
GROUP BY T1.preferred,T1.date_from,T1.date_to
)NIGHTS
ON T0.preferred = NIGHTS.preferred
AND T0.date_from = NIGHTS.date_from
AND T0.date_to = NIGHTS.date_to
WHERE
T0.date_from <= @checkout
AND T0.date_to >= @checkin
;
http://sqlfiddle.com/#!9/d64344/10 あなたは、実際のチェックインと@checkout
と@checkin
出現を交換し、時間をチェックアウトすることができます。 、あなたの実際のテーブル名
私は、テーブルに滞在可能日数のどんな最大数に上向きにカウント0から番号を含む列n
と呼ばれる番号が含まれているsqlfiddleにそうそうでYourTable
発生を置き換えることができます。このテーブルも作成する必要があります。テーブル番号を作成する
は
CREATE TABLE numbers AS
SELECT a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n as n
FROM
(SELECT 0 as n UNION SELECT 1)a,
(SELECT 0 as n UNION SELECT 2)b,
(SELECT 0 as n UNION SELECT 4)c,
(SELECT 0 as n UNION SELECT 8)d,
(SELECT 0 as n UNION SELECT 16)e,
(SELECT 0 as n UNION SELECT 32)f,
(SELECT 0 as n UNION SELECT 64)g,
(SELECT 0 as n UNION SELECT 128)h,
(SELECT 0 as n UNION SELECT 256)i;
1以下)サブクエリDAYS1範囲に
を@checkoutする@checkinからのすべての単一の日付 を返す使用します2)T1はDAYS1と結合されています。 が優先されているか、または優先行が存在しません。 ERS DAYS1の日付
3)その後、我々はDATE_TOは、単一の日
4の数を取得するには、 好ましく、DATE_FROM BY COUNT(*)GROUPを行う)その後、我々は、我々の結果NIGHTS
5呼び出します)その後、T0はNIGHTSでLEFT JOINEDされ、0の行を持つ偶数行を取得します。
6)@ checkin/@ checkout範囲を傍受するT0行のみを返します。
UPDATEあなたの表は、あなたがしようとすると、あなたがこの
SET @checkin = '2016-01-16';
SET @checkout = '2016-02-08';
SELECT T0.preferred,T0.date_from,T0.date_to,IFNULL(NIGHTS.nights,0) as Nights
FROM (SELECT * FROM YourTable WHERE date_from <= @checkout AND date_to >= @checkin) T0
LEFT JOIN
(SELECT T1.preferred,T1.date_from,T1.date_to,COUNT(*) AS Nights
FROM (SELECT * FROM YourTable WHERE date_from <= @checkout AND date_to >= @checkin) AS T1
INNER JOIN
(SELECT (@checkin + INTERVAL n DAY) as singleday
FROM numbers
WHERE (@checkin + INTERVAL n DAY) <= @checkout)DAYS1
ON DAYS1.singleday BETWEEN T1.date_from AND T1.date_to
WHERE T1.preferred = 1
OR NOT EXISTS
(SELECT 1
FROM (SELECT * FROM YourTable WHERE date_from <= @checkout AND date_to >= @checkin) AS T
WHERE T.preferred = 1
AND DAYS1.singleday BETWEEN T.date_from AND T.date_to
)
GROUP BY T1.preferred,T1.date_from,T1.date_to
)NIGHTS
ON T0.preferred = NIGHTS.preferred
AND T0.date_from = NIGHTS.date_from
AND T0.date_to = NIGHTS.date_to
;
03ので、同じように興味を持っている行のみを使用してサブクエリを絞り込むことができます大きすぎる - 08秒間隔OR 03で覆われています - 10 #typo – diEcho
@diEcho私はそれがtypoだとは思わない03-08は第2の間隔でカバーされています09と10はチェックイン/チェックアウトの範囲外のため無視されます –