0

このテーブルがあるとします..

CREATE TABLE `appointments` (
  `idappointments` int(11) NOT NULL AUTO_INCREMENT,
  `timeStart` time DEFAULT NULL,
  `timeEnd` time DEFAULT NULL,
  PRIMARY KEY (`idappointments`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8$$

予測

timeStart と timeEnd の間の範囲が再び存在できないとします...つまり、テーブル内のすべての範囲と交差すると、結果は EMPTY ,0 , null になります。予定は別の予定と共存できません..

そこでやりたいのは、希望時間が埋まっていたら時間の提案… 希望時間前の提案と、希望時間後の提案…。

だから、これを行うコードを書く代わりに、SQLクエリを書いて最も近い空の範囲を見つけることができるかどうか疑問に思っていました......

例: timeStart - NEAREST_TO_TIMESTART_TIMEEND >'10 minutes' の場合、期間は 10 分です

4

1 に答える 1

2

MySQL には再帰機能がないため、NUMBERS テーブル トリックを使用する必要があります。

  1. 増加する数値のみを保持するテーブルを作成します - auto_increment を使用して簡単に実行できます:

    DROP TABLE IF EXISTS `example`.`numbers`;
    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
       PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
  2. 以下を使用してテーブルにデータを入力します。

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...必要な数の値に対して。

  3. DATE_ADDを使用して日付のリストを作成し、NUMBERS.id 値に基づいて日数を増やします。"2010-01-01" と "2010-01-02" をそれぞれの開始日と終了日に置き換えます (ただし、YYYY-MM-DD HH:MM:SS という同じ形式を使用します) -

    SELECT x.dt
      FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
              FROM numbers n
             WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
    
  4. 日時部分に基づいて、データのテーブルに LEFT JOIN します。

これにより、最初に利用可能なスロットが表示されます。

       SELECT x.dt
      FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
              FROM numbers n
             WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
    LEFT JOIN APPOINTMENTS a ON x.dt BETWEEN a.timestart AND a.timeend
        WHERE a.idappoinment IS NULL
          AND x.dt > @your_minimum_datetime
     ORDER BY x.dt
        LIMIT 1

これにより、1 日の空き状況が表示されます。

       SELECT x.dt,
              CASE 
                WHEN a.idappoinment IS NULL THEN 'available'
                ELSE 'booked'
              END AS isbooked 
      FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
              FROM numbers n
             WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
    LEFT JOIN APPOINTMENTS a ON x.dt BETWEEN a.timestart AND a.timeend
     ORDER BY x.dt

なぜ日付ではなく数字なのですか?

シンプル - 私が提供した例のように、数値に基づいて日付を生成できます。また、データ型ごとに 1 つのテーブルを使用するのではなく、1 つのテーブルを使用することも意味します。

于 2010-09-16T19:39:04.467 に答える