2014-07-07 53 views
0

我目前正在預訂系統上工作。我目前遇到問題,無法確定一間公寓是否已經預訂完畢。在我的數據庫中,我有一張桌子,裏面有所有的公寓及其詳細信息。我試圖得到所有的公寓,例如4間臥室的預訂日期。我運行以下sql返回所有4間臥室公寓的預訂日期。如何驗證房間是否已預訂完畢?

SELECT * 
FROM `apartment_booking` AS ab 
JOIN apartment AS a ON (a.id = apartmentId) 
JOIN booking AS b ON (b.id = bookingId) 
WHERE bedrooms = '4' 
ORDER BY checkIn 

的sql的回報是

id CheckIn  checkOut  userId 
74 2014-04-15 2014-04-22 1 
75 2014-04-15 2014-04-22 1 
102 2014-06-03 2014-07-07 1 
71 2014-06-16 2014-06-23 1 
114 2014-07-19 2014-08-02 1 
121 2014-07-20 2014-08-02 1 
57 2014-07-22 2014-08-05 1 
122 2014-07-28 2014-08-02 1 
117 2014-08-03 2014-08-10 1 

正如我在四房系統4套公寓我想獲得所有四個房間都預訂的日期。

舉例說明2014-07-28至2014-08-02日期的產品已完全預訂,因爲在該日期範圍內共有四次預訂。

數據庫:

CREATE TABLE `apartment` (
    `id` int(11) NOT NULL auto_increment, 
    `code` varchar(4) NOT NULL, 
    `bedrooms` int(11) NOT NULL, 
    `description` varchar(500) default NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=26 ; 

-- 
-- Dumping data for table `apartment` 
-- 

INSERT INTO `apartment` (`id`, `code`, `bedrooms`, `description`) VALUES 
(1, '1c', 3, ''), 
(4, '4d', 4, NULL), 
(5, '5b', 2, NULL), 
(10, '10c', 3, NULL), 
(11, '11b', 2, NULL), 
(12, '12d', 4, NULL), 
(13, '13c', 3, NULL), 
(14, '14a', 1, 'Yo'), 
(15, '15b', 2, NULL), 
(16, '16b', 2, NULL), 
(17, '17d', 4, NULL), 
(22, '22d', 4, NULL), 


CREATE TABLE `apartment_booking` (
    `id` int(11) NOT NULL auto_increment, 
    `apartmentId` int(11) NOT NULL, 
    `bookingId` int(11) NOT NULL, 
    `ref` varchar(50) NOT NULL, 
    `pax` int(11) NOT NULL default '1', 
    `remarks` varchar(500) default NULL, 
    `guestFullName` varchar(30) default NULL, 
    `guestCountry` varchar(2) default NULL, 
    `guestFlightDetails` varchar(200) default NULL, 
    PRIMARY KEY (`id`), 
    KEY `apartmentId` (`apartmentId`), 
    KEY `bookingId` (`bookingId`), 
    KEY `ref` (`ref`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=179 ; 

-- 
-- Dumping data for table `apartment_booking` 
-- 

INSERT INTO `apartment_booking` (`id`, `apartmentId`, `bookingId`, `ref`, `pax`, `remarks`, `guestFullName`, `guestCountry`, `guestFlightDetails`) VALUES 
(164, 1, 140, 'Hotelbeds', 5, '', 'Andrew Robertson', 'MT', '') 
(165, 21, 141, 'Hotelbeds', 6, '', 'Pipitone', 'MT', ''), 
(166, 5, 142, 'maltaholidaylets', 2, '', 'holly turpin', 'MT', ''), 
(167, 12, 143, 'direct003', 4, '', 'Bernard Walch', 'MT', ''), 
(168, 17, 144, 'meetingpoint', 4, '', 'Edvin Modigh', 'MT', ''), 
(169, 23, 145, 'direct', 3, '', 'Andrea bacchetti', 'MT', ''), 
(172, 25, 148, 'direct', 5, '', 'Wimold Peters', 'MT', ''), 
(173, 20, 149, '7228110687', 4, '', 'Ms. Benedetta Tombari', 'MT', ''), 
(174, 23, 149, '7228110687 meetingpoint', 2, '', 'Ms. Milena Moretti', 'MT', ''), 
(175, 25, 150, 'meetingpoint', 6, '', 'N Burdett', 'MT', ''), 
(176, 8, 151, 'Hotelbeds', 2, '', 'tito titti', 'MT', ''), 
(177, 1, 152, 'meetingpoint', 3, '', 'Stephen Mckenna', 'MT', ''), 
(178, 16, 153, 'mhcs', 4, '', 'Wojclech Blaszak', 'MT', ''); 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `booking` 
-- 

CREATE TABLE `booking` (
    `id` int(11) NOT NULL auto_increment, 
    `reference` varchar(20) NOT NULL, 
    `dateTime` datetime NOT NULL, 
    `checkIn` date NOT NULL, 
    `checkOut` date NOT NULL, 
    `userId` int(11) default NULL, 
    PRIMARY KEY (`id`), 
    KEY `agent` (`userId`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=154 ; 

-- 
-- Dumping data for table `booking` 
-- 

INSERT INTO `booking` (`id`, `reference`, `dateTime`, `checkIn`, `checkOut`, `userId`) VALUES 
(136, 'euroresort booking.b', '2014-07-02 09:30:08', '2014-08-04', '2014-08-11', 1), 
(137, '7014505534', '2014-07-02 09:32:05', '2014-07-19', '2014-07-24', 1), 
(138, 'BR4277518', '2014-07-02 09:45:02', '2014-08-09', '2014-08-16', 1), 
(139, '100206154', '2014-07-02 10:11:45', '2014-07-27', '2014-08-03', 1), 
(140, '120-135249-95', '2014-07-02 10:13:14', '2014-07-02', '2014-07-03', 1), 
(141, '120-135181-94', '2014-07-02 10:14:31', '2014-08-10', '2014-08-17', 1), 
(142, '000548MHL', '2014-07-02 12:38:54', '2014-08-25', '2014-09-01', 1), 
(143, 'direct003', '2014-07-02 15:48:04', '2014-08-11', '2014-08-22', 1), 
(144, 'SH3049361', '2014-07-02 15:52:18', '2014-08-05', '2014-08-14', 1), 
(145, 'direct009', '2014-07-03 08:27:56', '2014-07-19', '2014-07-26', 1), 
(148, 'direct010', '2014-07-04 08:12:13', '2014-07-08', '2014-07-22', 1), 
(149, '7228110687', '2014-07-04 13:28:16', '2014-08-10', '2014-08-16', 1), 
(150, '7308310623', '2014-07-07 08:39:04', '2014-08-11', '2014-08-20', 1), 
(151, '120-135677-92', '2014-07-07 08:43:06', '2014-08-22', '2014-08-29', 1), 
(152, '100209964', '2014-07-07 10:59:16', '2014-08-05', '2014-08-12', 1), 
(153, 'mhcs', '2014-07-07 13:07:22', '2014-08-08', '2014-08-16', 1); 
+0

您可以發佈您的表聲明討好(和一些樣本數據)?目前,我不知道您的預訂表是否每天預訂一個房間,或者每個預訂只有一行開始和結束日期。 – Kickstart

+0

我已經爲數據庫 – eric

回答

1

它變得有點複雜。

以下查詢生成一系列從0到999的數字,並將每個數字作爲天數添加到每個預訂的checkIn日期,其中結果日期小於或等於預訂的checkOut日期4間客房的公寓。這應該預訂每間公寓一行。

然後計算每個日期的預訂ID的數量,並與具有4間臥室的公寓的數量(來自子查詢)進行比較。然後,HAVING子句放棄所有記錄日期的行,其中預訂的公寓數量與具有4個房間的公寓數量不同。

SELECT aBookedDate, sub2.apartment_cnt, COUNT(id) AS all_booking_cnt 
FROM 
(
    SELECT booking.id, DATE_ADD(booking.checkIn, INTERVAL iCnt DAY) AS aBookedDate 
    FROM 
    (
     SELECT units.i + tens.i * 10 + hundreds.i * 100 AS iCnt 
     FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)units 
     CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)tens 
     CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)hundreds 
    ) sub0 
    CROSS JOIN booking 
    INNER JOIN apartment_booking ON booking.id = apartment_booking.bookingId 
    INNER JOIN apartment ON apartment.id = apartment_booking.apartmentId 
    WHERE DATE_ADD(booking.checkIn, INTERVAL iCnt DAY) <= booking.checkOut 
    AND apartment.bedrooms = 4 
) sub1 
CROSS JOIN 
(
    SELECT COUNT(*) AS apartment_cnt 
    FROM apartment 
    WHERE bedrooms = 4 
) sub2 
GROUP BY aBookedDate 
HAVING all_booking_cnt = sub2.apartment_cnt 

它SQL小提琴: -

http://www.sqlfiddle.com/#!2/6edbe/5

+0

感謝所以mucyh :)救生員:) – eric

0

你需要左外連接,所以你也表明,沒有預訂的公寓。

SELECT * 
FROM `apartment_booking` AS ab 
JOIN apartment AS a ON (a.id = apartmentId) 
JOIN booking AS b ON (b.id = bookingId) 
WHERE bedrooms = '4' and userId is null 
ORDER BY checkIn 

因爲沒有預訂連接到該公寓,所以具有空用戶標識的個人將爲空(也稱爲非預訂)。你沒有說足夠的結構,所以我認爲你刪除了預訂而不是保留歷史。如果保留所有歷史記錄,則需要使用今天的日期檢查日期。

SELECT * 
FROM `apartment_booking` AS ab 
JOIN apartment AS a ON (a.id = apartmentId) 
LEFT OUTER JOIN booking AS b ON (b.id = bookingId) 
WHERE bedrooms = '4' and checkOut > NOW() 
ORDER BY checkIn 

編輯:

它應該是這個樣子,我會盡力與後面準備小提琴:

SELECT 
    (COUNT( 
     SELECT * 
     FROM `apartment_booking` AS ab 
     JOIN apartment AS a ON (a.id = apartmentId) 
     LEFT OUTER JOIN booking AS b ON (b.id = bookingId) 
     WHERE bedrooms = '4' and checkIn <= <<<SOMEDATEHERE>>> and checkOut >= <<<<SOMEOTHERDATEHERE>>>>> 
    ) >= 4); 
+0

添加了sql首先感謝您的幫助,但我不認爲你瞭解我,我的問題是從我需要驗證的回報(因爲我有4間臥室的4個公寓),如果與簽入日期有在這個回報中預訂日期已滿,預訂日期將是28-7至2-8,因爲在同一日期範圍內有4次預訂 – eric

+1

我不知道你的意思是什麼。請在你的問題中輸入預期的OUTPUT例子。 – mareckmareck

+0

由於我有四間臥室的系統中的公寓,我想獲得所有四間臥室的預訂日期。 舉例說明2014-07-28至2014-08-02日期的產量已完全預訂,因爲在該日期範圍內共有四次預訂。 – eric