Entity Room and Reservation
Room=Room_id,Rtype,Occupied(Bit column)
Reservation =Res_id,Room_id,CheckinDate,CheckoutDate.
How to update Occupied bit column to 1 when a room is reserved in Reservations table?I think its a trigger.but how?code snippet as I am new to this.
Someone suggested using check out date as Null.If null then update Occupied to 1.
HElp!!
The problem with using a static placement field like the Occupied one you have is that the value will change depending on the date you are reviewing. For example: Room A is unoccupied now, but is reserved two days from now for a 3 night stay, if you change the Occupied field to 1 then it will incorrectly show up as Occupied if someone tries to check-in today.
You will also have the problem of changing the Occupied field back to 0 when the room isn't in use - this is creating more work than necessary.
As mentioned in the comments it would be best to not have the Occupied field at all and instead create queries that will show when a room is available or not. The query can really vary depending on what you want, below is a sample query that creates a stored procedure that can be used to find available rooms during a date range:
CREATE PROCEDURE CheckRoomAvailability
#NewCheckInDate DATETIME
#NewCheckOutDate DATETIME
AS
SELECT r.Room_ID, r.Rtype
FROM room AS r
INNER JOIN reservation as re
ON r.room_id = re.room_id
WHERE
(#NewCheckINDate < re.CheckinDate
OR
#NewCheckInDate > re.CheckoutDate)
AND
(#NewCheckOutDate < re.CheckinDate
OR
#NewCheckOutDate > re.CheckoutDate)
GO
Then to execute this stored procedure:
EXEC CheckRoomAvailability([Check-In Date],[Check-Out Date])
Just enter the desired dates into the statement.
select checkoutdate from Reservation;
Put checkoutdate on a variable.
if checkoutdate == null then
update Room set occupied = 1;
Related
I have a database with a table which I use as master and which is being updated and extended on a daily basis by a table with the same layout. Before I update almost the whole master with daily data, I want to test if the values from a specific column changed during the daily update. Usually this column only contains Null or an "X".
As a prototype I only compared the specific column of Table A and Table B and if there is a difference, set a value with more than one characters into the column (here yesterday's date).
This is the code which worked as a prototype:
UPDATE ReiseMaster
INNER JOIN Update_Import
ON(ReiseMaster.Col3 <> Update_Import.Col3
SET ReiseMaster.Col3 = Date() - 1
Now, the column contains Null, "X" or a date in the master. For the next update I now have to make sure that this previously updated column values which are containing a date as a string will be excluded (otherwise ReiseMaster.Col3 <> Update_Import.Col3 will always be true for them in the future and the date will always be updated which is not intended to happen).
My approach was to exclude all datasets from the master table where the length of the values in the column is longer than 1.
Now here is my problem:
Running the SQL code makes MS Access not responding anymore, the whole program crashes. Can somebody advise me what could be wrong with the following code?
UPDATE ReiseMaster
INNER JOIN ReiseMaster_Import
ON(ReiseMaster.`Attachment Indicator` <> ReiseMaster_Import.`Attachment Indicator` AND LEN(ReiseMaster.`Attachment Indicator`) <= 1)
SET ReiseMaster.`Attachment Indicator` = Date() - 1
Additional info: I use Access VBA to run a code and during that also the SQL-statements which are being saved in a string. About the reason I add a date once I observe a change, I want to use the dates as a reference when the value has been changed for the first time to do further analysis with them in a later stage.
Avoid using complex joins in update queries! Since the entire recordset needs to be updateable, Access tends to have problems with it.
Instead, use a WHERE clause:
UPDATE ReiseMaster
INNER JOIN ReiseMaster_Import
ON(ReiseMaster.[Attachment Indicator] <> ReiseMaster_Import.[Attachment Indicator])
SET ReiseMaster.[Attachment Indicator] = Date() - 1
WHERE LEN(ReiseMaster.[Attachment Indicator]) <= 1
Also, Access uses brackets to escape spaces in column names.
Note that if you're not using any information from the joined table, and just use it to select records, you should use an Exists clause instead:
UPDATE ReiseMaster
SET ReiseMaster.[Attachment Indicator] = Date() - 1
WHERE EXISTS(SELECT 1 FROM ReiseMaster_Import WHERE ReiseMaster.[Attachment Indicator] <> ReiseMaster_Import.[Attachment Indicator])
AND LEN(ReiseMaster.[Attachment Indicator]) <= 1
So we have an application that stores lap times for runners the tables are a bit like this.
Runner Table
ID|AGE|LastLap|BestLap
Laps Table
ID|Time|Date|Inserted|RunnerID
So are application had/has a bug in it that when you add a lap that was in the past from your last lap it still set the last lap id when it did not need to.
What I want to do is fix the lastlap column so that the true last lap id for each runner is the last lap id do by ordering laps table by Date for each runner but i can't figure out a SQL update script to do this. I get very close but I can't get the ID from the laps table or I get more than one result.
I'd follow Mike's statement: if it isn't some crazy performance-tuning thing, stick with a view for cases like "last..." "best...", it can minimize any hassle in this regard.
Anyways, if you "just" need to update what's broken, the following should work with MS SQL, if not great performance-wise.
Presumptions: "time" is your business-value for the lap, not time of day; "inserted" and "ID" can't be used, because someone may insert data not ordered by date.
This means: if you have more then one lap-entry per runner per day, you just have to assume that the biggest ID has your desired business-value or change your data-model.
DECLARE #RunnerID INT;
SET #RunnerID = yourRunnerID;
UPDATE RUNNERS
SET LastLap = (SELECT MAX(L.ID)
FROM Laps L
WHERE L.RunnerID = #RunnerID
AND L.DATE = (SELECT MAX(Date)
FROM Laps
WHERE Laps.RunnerID = #RunnerID
)
)
WHERE ID = #RunnerID;
I’m in the process of creating a report that will tell end users what percentage of a gridview (the total number of records is a finite number) has been completed in a given month. I have a gridview with records that I’ve imported and users have to go into each record and update a couple of fields. I’m attempting to create a report tell me what percentage of the grand total of records was completed in a given month. All I need is the percentage. The grand total is (for this example) is 2000.
I’m not sure if the actual gridview information/code is needed here but if it does, let me know and I’ll add it.
The problem is that I have been able to calculate the percentage total but when its displayed the percentage total is repeated for every single line in the table. I’m scratching my head on how to make this result appear only once.
Right now here’s what I have for my SQL code (I use nvarchar because we import from many non windows systems and get all sorts of extra characters and added spaces to our information):
Declare #DateCount nvarchar(max);
Declare #DivNumber decimal(5,1);
SET #DivNumber = (.01 * 2541);
SET #DateCount = (SELECT (Count(date_record_entered) FROM dbo.tablename WHERE date_record_entered IS NOT NULL and date_record_entered >= 20131201 AND date_record_entered <= 20131231);
SELECT CAST(ROUND(#DivNumber / #DateCount, 1) AS decimal(5,1) FROM dbo.tablename
Let’s say for this example the total number of records in the date_record_entered for the month of December is 500.
I’ve tried the smaller pieces of code separately with no success. This is the most recent thing I’ve tried.
I know I'm missing something simple here but I'm not sure what.
::edit::
What I'm looking for as the expected result of my query is to have a percentage represented of records modified in a given month. If 500 records were done that would be 25%. I just want to have the 25 (and trainling decimal(s) when it applies) showing once and not 25 showing for every row in this table.
The following query should provide what you are looking for:
Declare #DivNumber decimal(5,1);
SET #DivNumber = (.01 * 2541);
SELECT
CAST(ROUND(#DivNumber / Count(date_record_entered), 1) AS decimal(5,1))
FROM dbo.tablename
WHERE date_record_entered IS NOT NULL
and date_record_entered >= 20131201
AND date_record_entered <= 20131231
Why do you select the constant value cast(round(#divNumber / #DateCount, 1) as decimal(5,1)from the table? That's the cause of your problem.
I'm not too familiar with sql server, but you might try to just select without a from clause.
select emp.Natinality_Id,mstn.Title as Nationality,count(emp.Employee_Id) as Employee_Count,
count(emp.Employee_Id)* 100.0 /nullif(sum(count(*)) over(),0) as Nationality_Percentage
FROM Employee as emp
left join Mst_Natinality as mstn on mstn.Natinality_Id = emp.Natinality_Id
where
emp.Is_Deleted='false'
group by emp.Natinality_Id,mstn.Title
Essentially i'm making a basic hotel booking system for my computing a-level coursework, and have hit a stumbling block (doesn't help having a migraine either!)
I'm in the process of checking if a room is available for then the user to book (the application is all run and used by staff by the way) but trying to get my head around how to do it.
At the moment I was thinking I could just search the current booking database for the room number and dates I want to book for and if a match came back that meant that certain room was booked. That's all fine and dandy, but how do I tell it the range of dates? (sorry bad question) I was thinking an pseudo code version of the sql statement on the lines of:
If 'check in date of booking already on the database' is before
'check in date of new booking' AND 'check out date of booking already
on the database' is after 'check in date of new booking' then room is
already booked.
Basically if it returns a record then I know that room is booked. But I just need to figure out how to use SQL to search for records based on my check in/out dates.
But that'll allow double bookings, agh it's driving me mad :/ Any ideas?
It may not seem totally obvious at first, but you can actually simplify the testing of a full or partial date overlap with just two conditions.
Let's say you've got BOOKING table with existing bookings and a new booking with check in date #NEW_CHECK_IN and check out date #NEW_CHECK_OUT. To find all bookings that overlap these dates (assuming the end points are inclusive) you just need this kind of where clause:
--Select overlapping bookings
-- ...
WHERE BOOKING.CHECK_IN <= #NEW_CHECK_OUT
AND BOOKING.CHECK_OUT >= #NEW_CHECK_IN
-- ...
I know it looks too simple, but try it out with the scenarios that drf illustrated (plus the three that were missed, (1) where the new booking is after the existing booking, (2) the new booking is strictly within the existing booking and (3) the new booking is equal to the existing booking). You'll see that this simple set of conditions covers all of these scenarios.
The pseudocode suggested only considers one possibility of conflict between an existing booking and a new booking. To illustrate, consider a room with one booking.
|======================|
Check-in date Check out date
Suppose we want to create a new booking, and have 4 potential new bookings.
|======================| Existing booking
|-----------------------------| New booking (Scenario 1)
|----------| New booking (Scenario 2)
|-------------| New booking (Scenario 3)
|---| New booking (Scenario 4)
Of these, only Scenario 4 does not overlap an existing booking; the others conflict with the existing booking. While your pseudocode addresses Scenario 1, it does not detect Scenarios 2 or 3 and will thus allow double-bookings.
Effectively, your pseudocode might look something like this.
Let E = booking already on the database
N = new booking,
CID = check-in date,
COD = check-out date
For a new booking N, N conflicts with an existing booking iff there exists a record E where:
(CID of E is between CID of N and COD of N), or
(COD of E is between CID of N and COD of N), or
(CID of N < CID of E and COD of N > COD of E)
In SQL, depending on your schema, the query might resemble something like this:
-- assume #new_cid is the new checkin date and #new_cod is the new checkout date
select count(*) from bookings
where
#new_cid between bookings.checkindate and bookings.checkoutdate or
#new_cod between bookings.checkindate and bookings.checkoutdate or
(#new_cid <= bookings.checkindate AND #new_cod > bookings.checkoutdate)
I have a table with actions that are being due in the future. I have a second table that holds all the cases, including the due date of the case. And I have a third table that holds numbers.
The problems is as follows. Our system automatically populates our table with future actions. For some clients however, we need to change these dates. I wanted to create an update query for this, and have this run through our scheduler. However, I am kind of stuck at the moment.
What I have on code so far is this:
UPDATE proxima_gestion p
SET fecha = (SELECT To_char(d.f_ult_vencim + c.hrem01, 'yyyyMMdd')
FROM deuda d,
c4u_activity_dates c,
proxima_gestion p
WHERE d.codigo_cliente = c.codigo_cliente
AND p.n_expediente = d.n_expediente
AND d.saldo > 1000
AND p.tipo_gestion_id = 914
AND p.codigo_oficina = 33
AND d.f_ult_vencim > sysdate)
WHERE EXISTS (SELECT *
FROM proxima_gestion p,
deuda d
WHERE p.n_expediente = d.n_expediente
AND d.saldo > 1000
AND p.tipo_gestion_id = 914
AND p.codigo_oficina = 33
AND d.f_ult_vencim > sysdate)
The field fecha is the current action date. Unfortunately, this is saved as a char instead of date. That is why I need to convert the date back to a char. F_ult_vencim is the due date, and hrem01 is the number of days the actions should be placed away from the due date. (for example, this could be 10, making the new date 10 days after the due date)
Apart from that, there are a few more criteria when we need to change the date (certain creditors, certain departments, only for future cases and starting from a certain amount, only for a certain action type.)
However, when I try and run this query, I get the error message
ORA-01427: single-row subquery returns more than one row
If I run both subqueries seperately, I get 2 results from both. What I am trying to accomplish, is that it connects these 2 queries, and updates the field to the new value. This value will be different for every case, as every due date will be different.
Is this even possible? And if so, how?
You're getting the error because the first SELECT is returning more than one row for each row in the table being updated.
The first thing I see is that the alias for the table in UPDATE is the same as the alias in both SELECTs (p). So all of the references to p in the subqueries are referencing proxima_gestion in the subquery rather than the outer query. That is, the subquery is not dependent on the outer query, which is required for an UPDATE.
Try removing "proxima_gestion p" from FROM in both subqueries. The references to p, then, will be to the outer UPDATE query.