使用联合查询下拉列表

时间:2016-11-25 04:53:53

标签: mysql sql union

我正在开发一个预订系统,并且在我的预订表格中我有一个下拉元素,它返回(仍然)预订系统的可用开始时间段。

通过创建新预订,我创建的查询工作正常,并且正确返回所有可用的开始时间段。

QUERY:

 WHERE {thistable}.id 
 IN (
     SELECT id +3 
     FROM (
           SELECT p1.book_date, t.*,   count(p1.book_date) AS nbre 
           FROM fab_booking_taken AS p1 
           CROSS JOIN fab_booking_slots AS t 
           WHERE NOT ((t.heuredepart_resa < p1.book_end AND 
                 t.heurearrivee_resa > p1.book_start)) 
                 AND DATE(p1.book_date)=DATE('{fab_booking___book_bookingdate}') 
           GROUP BY t.id) AS x 
           WHERE nbre =
           (
            SELECT count(p2.book_date) 
            FROM fab_booking_taken AS p2 
            WHERE p2.book_date = x.book_date
           )
    ) ORDER BY id ASC

请观看视频:booking creationg

我通过编辑现有预订使用相同查询的问题返回了可用的开始时间段,这很好:

18时 18:30 19:00 19:30

但不是已经由我选择的客户(以及在数据库中保存的)时间段,这在我的例子中是14:00。

请观看视频:Editing booking with same query

下拉列表应填充以下选项:

14:00 18:00 18:30 19:00 19:30

我尝试创建一个联合查询,以便通过客户选择的开始时间段和(仍然)可用的开始时间段来获取。

QUERY:

 {thistable}.id 
 IN ( 
     SELECT id + 3 
     FROM ( 
           SELECT p1.book_date, t.*, count(p1.book_date) AS nbre 
           FROM fab_booking_taken AS p1 
           CROSS JOIN fab_booking_slots AS t 
           WHERE NOT ((t.heuredepart_resa < p1.book_end 
             AND t.heurearrivee_resa > p1.book_start)) 
             AND p1.book_date = DATE_FORMAT('{fab_booking___book_bookingdate}', '%Y-%m-%d') 
           GROUP BY  t.id 
          ) as foobar2 
     UNION ( 
            SELECT id + 3 
            FROM ( 
                  SELECT  p1.book_date, t.*, count(p1.book_date) AS nbre 
                  FROM fab_booking_taken AS p1 
                  CROSS JOIN fab_booking_slots AS t  
                  WHERE ( ( t.heuredepart_resa < p1.book_end 
                    AND t.heurearrivee_resa > p1.book_start ) ) 
                    AND t.id = '{fab_booking___book_starttime}' 
                    AND p1.book_date = DATE_FORMAT('{fab_booking___book_bookingdate}', '%Y-%m-%d') 
                  GROUP BY t.id 
            ) AS x 
      WHERE nbre = ( 
                    SELECT count(p2.book_date) 
                    FROM fab_booking_taken AS p2 
                    WHERE p2.book_date = x.book_date 
                   ) 
            ) 
      )

已经由客户选择的开始时间段返回(14:00),但其他可用的返回开始时间段不正确。

请观看视频:Editing booking with union query

我被困住了,我不知道如何解决这个问题,所以我很感激你的帮助。

由于

相关数据库表

fab_booking与预订相关的视频

please download the sql table

fab_booking_taken已经存在25 11 2016年的预订id = 347

Please download the sql table

id 347是有关的预订

fab_booking_slots表,其中包含所有可能的时间段

Please download the sql table

fab_heuredepart_resa表,用于填充下拉元素

Please download the sql table

1 个答案:

答案 0 :(得分:0)

我必须承认,尝试解开该查询以理解其背后的逻辑是令人畏惧的,但我认为以下查询应该返回您需要的结果。

{thistable}.id IN (
    /*Finds booking slots where the booking slot does not overlap
      with any of the existing bookings on that day, 
      or where the booking slot id is the same as the current slot.*/
    SELECT t.id + 3
    FROM fab_booking_slots AS t 
    WHERE t.id = '{fab_booking___book_starttime}'
    OR NOT EXISTS (
        Select 1 
        From  fab_booking_taken AS p1
        Where Date(p1.book_date) = Date('{fab_booking___book_bookingdate}')
        And p1.book_end > t.heuredepart_resa 
        And p1.book_start < t.heurearrivee_resa
    )
)
Order By id Asc;

我很确定这在逻辑上是等价的,并且一旦以这样的简化形式表达,就更容易看到如何让它也能返回额外的时间段。

在为没有现有时段的新预订填充时段时,您应该使用单独的查询,在这种情况下,您只需删除单行t.id = '{fab_booking___book_starttime}' OR