Hotel Reservation System Sql Query? - sql

I want to build a Hotel Reservation System. For this system; database is also used fro an other program... But i have problem: before the reservation i want to see which number of rooms type are available for my for my reservation..
My table create sql querys
CREATE TABLE oteldb.oda (
oda_id INT (11) NOT NULL auto_increment,
oda_tip_id INT (11) DEFAULT NULL,
oda_adi VARCHAR (20) DEFAULT NULL,
PRIMARY KEY (oda_id)
)
ENGINE = MyISAM
AUTO_INCREMENT = 1
CHARACTER SET utf8
COLLATE utf8_general_ci;
CREATE TABLE oteldb.tip (
tip_id INT (11) NOT NULL auto_increment,
tip_adi VARCHAR (20) DEFAULT NULL,
PRIMARY KEY (tip_id)
)
ENGINE = MyISAM
AUTO_INCREMENT = 1
CHARACTER SET utf8
COLLATE utf8_general_ci
ROW_FORMAT = FIXED;
CREATE TABLE oteldb.rezervasyon (
rezervasyon_id INT (11) NOT NULL auto_increment,
rezervasyon_gt DATE DEFAULT NULL,
rezervasyon_ct DATE DEFAULT NULL,
rezervasyon_oda_id INT (11) DEFAULT NULL,
PRIMARY KEY (rezervasyon_id)
)
ENGINE = MyISAM
AUTO_INCREMENT = 1
CHARACTER SET utf8
COLLATE utf8_general_ci;
i try this but not work
SELECT
*
FROM
oteldb.tip
WHERE
IN tip.tip_id
(SELECT
oteldb.oda.oda_tip_id
FROM
oteldb.oda
WHERE
IN oda.oda_id note
(SELECT
oteldb.rezervasyon.rezervasyon_oda_id
FROM
oteldb.rezervasyon
WHERE
"2012-01-03" BETWEEN AND rezervasyon_ct rezervasyon_gt
AND "2012-01-22" AND BETWEEN rezervasyon_gt rezervasyon_ct))
thanks now...

Assuming that available rooms are those that are not already reserved at any time during the query period, and that rezervasyon_gt and rezervasyon_ct are the reservation start and end dates respectively, try:
select t.tip_adi, count(oda.oda_tip_id)
from oteldb.tip t
left join (select oda_tip_id
from oteldb.oda o
where not exists
(select null
from oteldb.rezervasyon r
where r.rezervasyon_oda_id = o.oda_id and
r.rezervasyon_gt <= '2012-01-22' and
'2012-01-03' <= r.rezervasyon_ct)
) oda on oda.oda_tip_id = t.tip_id
group by t.tip_adi

select
RoomType.tip_adi,
sum( if( Rooms.oda_id = BookedRooms.rezervasyon_oda_id, 0, 1 ) as AvailableCount
from
oteldb.oda Rooms
LEFT JOIN ( select distinct
res.rezervasyon_oda_id
from
oteldb.rezervasyo res
where
res.rezervasyon_gt between '2012-01-22' and '2012-01-03'
OR res.rezervasyon_ct between '2012-01-22' and '2012-01-03'
) BookedRooms
on Rooms.oda_id = BookedRooms.rezervasyon_oda_id
JOIN oteldb.tip RoomType
on Rooms.oda_tip_id = RoomType.tip_id

Related

SQL- Query Join 3 Tables, Group by a certain column and filter by Year?

Question:
What are the total distributions in 2020 from properties that were acquired in 2019 broken down by state?
So far this is what I have and seems like I am not getting it right to sum up? what step am I missing. I am not getting an error but not getting an answer either? Any ideas?
CREATE TABLE Property
(
hmy INT NOT NULL,
scode VARCHAR NOT NULL,
saddr1 VARCHAR NOT NULL,
saddr2 VARCHAR NOT NULL,
scity VARCHAR NOT NULL,
sstate VARCHAR NOT NULL,
szipcode INT NOT NULL,
PRIMARY KEY (hmy)
);
CREATE TABLE PropInfo
(
hmy INT NOT NULL,
hcode INT NOT NULL,
acquisitiondate DATE NOT NULL,
unitcount INT NOT NULL,
yearbuilt INT NOT NULL,
distributionentitycode VARCHAR NOT NULL,
PRIMARY KEY (hcode)
);
CREATE TABLE DistributionLog
(
hmy INT NOT NULL,
hcode INT NOT NULL,
distributionDate DATE NOT NULL,
distributiontype VARCHAR NOT NULL,
distributionamount INT NOT NULL,
PRIMARY KEY (hmy)
);
SELECT SUM(DL.distributionamount) AS Total, PY.sstate, PI.acquisitiondate, DL.distributionamount
FROM DistributionLog AS DL
JOIN PropInfo AS PI
ON PI.hmy = DL.hcode
JOIN Property AS PY
ON PY.hmy = PI.hmy
WHERE distributionDate BETWEEN '2020-1-1' AND '2020-12-31'
GROUP BY PY.sstate, PI.acquisitiondate, DL.distributionamount
ORDER BY PY.sstate;
Here's what was tried:
You can try something like this:
select p.sstate, sum(distributionamount)
from distributionlog d
inner join propinfo pi
on d.hcode = pi.hcode
and extract(year from acquisitiondate) = 2019
and extract(year from distributiondate) = 2020
inner join property p on pi.hmy = p.hmy
group by p.sstate
In this SQL, we are joining the 3 tables as you have been doing also. We are specifying during the join to ensure that acquisition date should be in 2019 and distribution date should be from 2020.
Since you want the sum(DL.distributionamount), DL.distributionamount should not be in group by clause. Below query should return you sstate wise sum(DL.distributionamount) for the properties that have been acquired in 2019 and distributed in 2020.(relation between tables is not clear to me without sample data. So I am assuming that you did the joining right)
SELECT PY.sstate, SUM(DL.distributionamount) AS Total
FROM DistributionLog AS DL
JOIN PropInfo AS PI
ON PI.hmy = DL.hcode and PI.acquisitiondate BETWEEN '2019-1-1' AND '2019-12-31'
JOIN Property AS PY
ON PY.hmy = PI.hmy
WHERE distributionDate BETWEEN '2020-1-1' AND '2020-12-31'
GROUP BY PY.sstate
ORDER BY PY.sstate;

SQL SELECT query not working

SELECT s1.id,
s3.food_name,
Count(*) AS TotalRefill
FROM (SELECT ( s1.food_value - s2.food_value ) AS difference
FROM `serving_info` s1,
`serving_info` s2
WHERE s1.id - s2.id = '1'
AND s1.food_name = 'Shrimp'
AND s2.food_name = 'Shrimp') AS diff,
`serving_info` s3
WHERE s3.id = diff.id
AND s3.food_value >= '990'
AND diff.difference >= '150'
Result: #1054 - Unknown column 's1.id' in 'field list'
--
-- Table structure for table `employees`
--
CREATE TABLE IF NOT EXISTS `employees` (
`id_user` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`email` varchar(64) NOT NULL,
`phone_number` varchar(16) NOT NULL,
`username` varchar(16) NOT NULL,
`password` varchar(32) NOT NULL,
`confirmcode` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id_user`),
KEY (name)
);
--
-- Table structure for table `Foods`
--
CREATE TABLE IF NOT EXISTS `Foods` (
`Food_name` varchar(40) NOT NULL,
`CostPerRefill` double NOT NULL,
PRIMARY KEY (`Food_name`)
);
--
-- Table structure for table `Serving_Info`
--
CREATE TABLE IF NOT EXISTS `Serving_Info` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`Food_Value` varchar(40) NOT NULL,
`Food_name` varchar(40) NOT NULL,
`Served_On` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`Oncall` varchar(128),
Foreign key(`Oncall`) REFERENCES `employees`(`name`),
Foreign key(`Food_name`) REFERENCES `Foods`(`Food_name`),
PRIMARY KEY (`id`),
UNIQUE (`Oncall`,`Food_name`, `Served_On`)
);
What is causing the s1 to not be declared? For some reason the s1 instance isn't detected by the s1.id. I have been trying to figure out from a while by changing different brackets but I really cannot figure out how to debug this..I have tried changing the position of the close bracket but that would mess up the query.
What all others here said is right, but just to give you a more preceise solution, look at the query below it should not be s1.id but it should be diff.id
SELECT diff.id,
s3.food_name,
Count(*) AS TotalRefill
FROM (SELECT ( s1.food_value - s2.food_value ) AS difference, s1.id
FROM `serving_info` s1,
`serving_info` s2
WHERE s1.id - s2.id = '1'
AND s1.food_name = 'Shrimp'
AND s2.food_name = 'Shrimp') AS diff,
`serving_info` s3
WHERE s3.id = diff.id
AND s3.food_value >= '990'
AND diff.difference >= '150'
S1is defined inside the parentheses and thus not visible outside them, where you reference it.
Because s1 is only defined in the inner select so not is scope. Select either diff.id or s3.id (they will be the same value as you are joining on it).
The table s1 is not in the from part of your query in which you are trying to select it, it's only in a subquery.

Mysql error 1111 in one version of query and error 1054 in another

I have two tables:
books: [isbn, book_title, publisher, ...]
inventory: [isbn, date, num_changed]
I want to return book titles for those which are on stock. I tried a join (query 1) and got 1054 error, then I substituted the reference with the literal value and now I get 1111 error.
query 1:
SELECT `books`.`isbn`, `books`.`book_title`, SUM( `inventory`.`numbers_changed` ) AS `num`
FROM `books`
INNER JOIN `inventory` ON `books`.`isbn` = `inventory`.`isbn`
WHERE `books`.`publisher` LIKE '%pint%'
AND `num` > '0'
query 2:
SELECT `books`.`isbn`, `books`.`book_title`, SUM( `inventory`.`numbers_changed` )
FROM `books`
INNER JOIN `inventory` ON `books`.`isbn` = `inventory`.`isbn`
WHERE `books`.`publisher` LIKE '%print%'
AND SUM( `inventory`.`numbers_changed` ) > '0'
What's the correct query to use?
Edit
Here are the create table queries:
CREATE TABLE IF NOT EXISTS `books` (
`isbn` varchar(30) CHARACTER SET ascii NOT NULL,
`book_title` varchar(255) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`date_published` varchar(10) CHARACTER SET ascii NOT NULL,
`author` varchar(40) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`translator` varchar(40) CHARACTER SET utf8 COLLATE utf8_persian_ci DEFAULT NULL,
`publisher` varchar(50) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`ganre` varchar(50) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`price` int(7) unsigned NOT NULL,
`cover_pic` int(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`isbn`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `inventory` (
`isbn` varchar(30) CHARACTER SET ascii NOT NULL,
`date` varchar(10) CHARACTER SET ascii NOT NULL,
`numbers_changed` int(5) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
The 1054 error is about referencing a column that doesn't exist. The actual error message would help to know what is causing the issue.
The 1111 error is because you're trying to use aggregate function (in this case, SUM) in the WHERE clause:
WHERE ...
AND SUM( `inventory`.`numbers_changed` ) > '0'
^
|__ see this?
...outside of a subquery. SQL statements are checked from bottom to top, so I expect that removing the SUM in the WHERE clause will show that the 1054 error is still unaddressed.
use having for second where argument
WHERE `books`.`publisher` LIKE '%print%'
HAVING ( COUNT(`inventory`.`numbers_changed`) > '0')
instead of
WHERE `books`.`publisher` LIKE '%print%'
AND SUM( `inventory`.`numbers_changed` ) > '0'

sql query is returning the same values twice

I have this sql query, and it should be returning two values, which is does but it returns each returned row twice, the sql looks like this,
SELECT * FROM `mailers`
LEFT JOIN `mailer_content` ON `mailers`.`id` = `mailer_content`.`mailer_id`
LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id`
WHERE `mailers`.`id` = 26
The table structure for the tables I am query look like this,
-- --------------------------------------------------------
--
-- Table structure for table `mailers`
--
CREATE TABLE `mailers` (
`id` int(11) NOT NULL auto_increment,
`mailer_title` varchar(150) NOT NULL,
`mailer_header` varchar(60) NOT NULL,
`mailer_type` enum('single','multi') NOT NULL,
`introduction` varchar(80) NOT NULL,
`status` enum('live','dead','draft') NOT NULL,
`flag` enum('sent','unsent') NOT NULL,
`date_mailer_created` int(11) NOT NULL,
`date_mailer_updated` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=29 ;
-- --------------------------------------------------------
--
-- Table structure for table `mailer_content`
--
CREATE TABLE `mailer_content` (
`id` int(11) NOT NULL auto_increment,
`headline` varchar(320) NOT NULL,
`content` text NOT NULL,
`mailer_id` int(11) NOT NULL,
`position` enum('left','right','centre') default NULL,
`tab_1_name` varchar(25) default NULL,
`tab_1_link` varchar(250) default NULL,
`tab_2_name` varchar(25) default NULL,
`tab_2_link` varchar(250) default NULL,
`tab_3_name` varchar(25) default NULL,
`tab_3_link` varchar(250) default NULL,
`tab_4_name` varchar(25) default NULL,
`tab_4_link` varchar(250) default NULL,
`created_at` int(10) NOT NULL,
`updated_at` int(10) NOT NULL,
PRIMARY KEY (`id`),
KEY `mailer_id` (`mailer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
-- --------------------------------------------------------
--
-- Table structure for table `mailer_images`
--
CREATE TABLE `mailer_images` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(150) NOT NULL,
`filename` varchar(150) NOT NULL,
`mailer_id` int(11) NOT NULL,
`content_id` int(11) default NULL,
`date_created` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=49 ;
I am sure that is must be a problem with my sql I just do not know what the problem is
If you use SELECT DISTINCT SQL will not return dupplicated rows, if there are some.
SELECT DISTINCT * FROM `mailers` LEFT JOIN `mailer_content` ON `mailers`.`id` = `mailer_content`.`mailer_id` LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id` WHERE `mailers`.`id` = 26
U can use group by smthng. It will delete the same records.
but u can delete nonsame rows. Use smthng without same values in different rows in original table.
try this
SELECT * FROM mailers
LEFT JOIN mailer_content ON mailers.id = mailer_content.mailer_id
LEFT JOIN mailer_images ON mailer_content.id = mailer_images.content_id
WHERE mailers.id = 26 GROUP BY mailers.id
It doesn't look like an SQL isse to me; I suspect this is more likely down to the data in your tables.
My guess is that there are two rows in mailer_content where mailers.id = 26 and then two rows (or possibly 1 and 3) in mailer_images for each of the mailer_contents.
How many rows do each of the following queries return?
SELECT * FROM `mailers`
WHERE `mailers`.`id` = 26
SELECT * FROM `mailer_content`
WHERE `mailer_content`.`id` = 26
My guess is that the first returns 1 row (because it has a primary key on id) and that the second returns two rows.
That all may be fine but my guess is that the following query returns 4 records:
SELECT * FROM `mailer_content`
LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id`
WHERE `mailer_content`.`id` = 26
Because either each content has two images each OR one content has one image and the other has three.

SQL joins query not acting as wanted

I have the following tables:
CREATE TABLE `attendance_event_attendance` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`talk_id` varchar(200) NOT NULL,
`membersAttended_id` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
KEY `attendance_event_attendance_9ace4e5a` (`talk_id`),
KEY `attendance_event_attendance_3c0dadb7` (`membersAttended_id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
CREATE TABLE `attendance_member` (
`name` varchar(200) NOT NULL,
`telephone_number` varchar(200) NOT NULL,
`email_address` varchar(200) NOT NULL,
`membership_type` varchar(1) NOT NULL,
`membership_number` varchar(200) NOT NULL,
PRIMARY KEY (`membership_number`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `attendance_talk` (
`title` varchar(200) NOT NULL,
`speaker` varchar(200) NOT NULL,
`date_of_talk` date NOT NULL,
PRIMARY KEY (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
I want to select all the members that have not attended the two latest talks. The query I have written looks like this:
SELECT m.name
from attendance_member as m
left outer join attendance_event_attendance as ea on (ea.membersAttended_id=m.membership_number)
join attendance_talk as t on (ea.talk_id = t.title)
where t.date_of_talk >= 2010-06-01
AND ea.membersAttended_id = null;
Is this correct? Or have I not understood joins correctly?
A somewhat horrible approach, I fear - but one that should work...
SELECT m.name
from attendance_member as m
left outer join (
SELECT ea.membersAttended_id
FROM attendance_event_attendance as ea
join attendance_talk as t on (ea.talk_id = t.title)
where t.date_of_talk >= 2010-06-01
GROUP BY ea.membersAttended_id
HAVING COUNT(*) = 2
) attendingmembers
ON attendingmembers.membersAttended_id = m.membership_number
WHERE attendingmembers.membersAttended_id IS NULL
Pretty much exactly like you would say it in English
Select Distinct m.name -- Select names
From attendance_member M -- of members
Where Not Exists -- who did not attend the last two talks
(Select * From attendance_event_attendance a
Join attendance_talk t
On a.talk_id = t.title
Where a.membersAttended_id = m.membership_number
And (Select Count(*) From attendance_talk
Where date_of_talk >= t. date_of_talk) <= 2)
NOTE: The subquery:
(Select * From attendance_event_attendance a
Join attendance_talk t
On a.talk_id = t.title
Where a.membersAttended_id = m.membership_number -- (correlated w/outer query)
And (Select Count(*) From attendance_talk
Where date_of_talk >= t. date_of_talk) <= 2)
returns the list of members who attended the talks which have 2 or fewer subsequent talks