MS Access SQL Date Range Query - sql

I am working on a classroom reservation tool. A core component is the ability to compare the requested date range to the existing reservations, to ensure that there is no overlap. I've read through several date range related questions here, and studied Salman's explanation and implementation of Allen's interval algebra ( SQL Query to Find Overlapping (Conflicting) Date Ranges ) until I understood it. Here's a stripped-down version of what I came up with.
tblRooms
roomID room
5 110
30 178
tblReservations
reservedID fkRoom dateIn dateOut
1 5 3/10/2017 3/15/2017
2 5 3/1/2017 3/3/2017
4 5 4/1/2017 4/30/2017
SELECT DISTINCTROW tblRooms.roomID, tblRooms.room
FROM tblRooms LEFT JOIN tblReservations
ON tblRooms.roomID = tblReservations.fkRoom
WHERE NOT Exists (
SELECT DISTINCT tblRooms.roomID
FROM tblRooms
WHERE ((tblReservations.[dateOut] >= #3/3/2017#)
AND (#3/9/2017# >= tblReservations.[dateIn])));
I'm getting inconsistent returns. These dates will exclude room 110, as they should. Other test input (#3/4/2017# and #3/10/2017#, #4/1/2017# and #4/14/2017#) won't. I've tried combinations of "WHERE NOT (...", "WHERE Exists () = False", etc.
I work on a highly restrictive network, where I can't pull in templates at will - my only options when I create a database are "Blank" and "Web", so I've got to roll my own on this. I appreciate any assistance.

Can you try the following:
SELECT DISTINCTROW tblRooms.roomID, tblRooms.room
FROM tblRooms
WHERE NOT Exists (
SELECT 1
FROM tblReservations
WHERE
tblReservations.fkRoom = tblRooms.roomID
AND ((tblReservations.[dateOut] >= #3/3/2017#)
AND (#3/9/2017# >= tblReservations.[dateIn])));

For a reservation check query you would do this:
select ...
from tblRooms room
where not exists
( select *
from tblReservations r
where r.fkRoom = room.roomId and
end > r.[datein] and start < r.[dateout] );
BUT the important part is, pass those end and start as parameters instead of hardcoded values like you did. With hardcoded values you are always open to get wrong results or error. For example what is:
#3/9/2017# really? Its interpretation would depend on regional settings (I am not an access programmer so I might be wrong).

Related

Access 2013 Query, DateDiff from Consecutive Rows TimeStamps

I'm facing a problem successfully completing (running) a query on a singular table in Access 2013 using SQL to complete a Datediff on consecutive/Sequential rows of timestamps, which track status changes in tickets going through our ticketing system.
The table titled: dbo_Master3_FieldHistory, has a field which tracks timestamps each time a ticket's status changes. Unfortunately, it only includes 1 timestamp per change, meaning it doesn't inherently have a secondary timestamp for when the status is changed again, which I need to run a DateDiff to calculate AGE for tickets, based on Status.
I found a plausible solution for this on StackOverflow, linked below. When i tried to implement this solution, as is with minor adjustments, and including adjustments for filtering out old data and particular fields, it just freezes my Access program and never times out (have to force close Access)
Date Difference between consecutive rows
'This is the basic code, traslated from the linked StackOverflow solution to fit this tables fields (I believed)
SELECT T.mrID, T.mrSEQUENCE, T.mrUSERID, T.mrFIELDNAME, T.mrNEWFIELDVALUE, T.mrOLDFIELDVALUE, T.mrTIMESTAMP, T.mrNextTIMESTAMP, DateDiff("s",T.mrTIMESTAMP, T.mrNextTIMESTAMP) AS STATUSTIME
FROM (
SELECT T1.mrID, T1.mrSEQUENCE, T1.mrUSERID, T1.mrFIELDNAME, T1.mrNEWFIELDVALUE, T1.mrOLDFIELDVALUE, T1.mrTIMESTAMP,
(SELECT MIN(mrTIMESTAMP)
FROM dbo_MASTER3_FIELDHISTORY AS T2
WHERE T2.mrID = T1.mrID
AND T2.mrTIMESTAMP > T1.mrTIMESTAMP
) As mrNextTIMESTAMP
FROM dbo_MASTER3_FIELDHISTORY AS T1
) AS T
'This is the code that I wanted to use to account for filtering out two particular fields, limiting the data to tickets (mrID) newer than 1/1/2018 and only those where the mrFIELDNAME is mrSTATUS
SELECT T.mrID, T.mrSEQUENCE, T.mrUSERID, T.mrFIELDNAME, T.mrNEWFIELDVALUE, T.mrOLDFIELDVALUE, T.mrTIMESTAMP, T.mrNextTIMESTAMP, DateDiff("s",T.mrTIMESTAMP, T.mrNextTIMESTAMP) AS STATUSTIME
FROM (
SELECT T1.mrID, T1.mrSEQUENCE, T1.mrUSERID, T1.mrFIELDNAME, T1.mrNEWFIELDVALUE, T1.mrOLDFIELDVALUE, T1.mrTIMESTAMP,
(SELECT MIN(mrTIMESTAMP)
FROM dbo_MASTER3_FIELDHISTORY AS T2
WHERE mrFIELDNAME = "mrSTATUS"
AND T2.mrID = T1.mrID
AND T2.mrTIMESTAMP > T1.mrTIMESTAMP
) As T1.mrNextTIMESTAMP
FROM dbo_MASTER3_FIELDHISTORY AS T1
WHERE mrFIELDNAME = "mrSTATUS"
AND mrTIMESTAMP >= #1/1/2018#
) AS T;
Access freezes when I try to run these queries. I've tried several ways but can't get it to work
I was able to figure it out, thank you to those who took your time to read through this interesting challenge. Instead of using the second code set in the link provided, I utilized the first and it worked beautifully. With some additions to the code to account for other filters/criteria, I have the results I need.
SELECT T1.mrID, T1.mrSEQUENCE, T1.mrUSERID, T1.mrFIELDNAME, T1.mrNEWFIELDVALUE, T1.mrOLDFIELDVALUE, T1.mrTIMESTAMP, MIN(T2.mrTIMESTAMP) AS mrNextTIMESTAMP, DATEDIFF("s", T1.mrTIMESTAMP, MIN(T2.mrTIMESTAMP)) AS TimeInStatus
FROM ((dbo_MASTER3_FIELDHISTORY AS T1 LEFT JOIN dbo_MASTER3_FIELDHISTORY AS T2 ON (T2.mrTIMESTAMP > T1.mrTIMESTAMP) AND (T1.mrID = T2.mrID)) INNER JOIN dbo_MASTER3 AS T4 ON (T4.mrID = T1.mrID))
WHERE T4.mrSUBMITDATE >= #1/1/2018#
AND t1.mrFIELDNAME = "mrSTATUS"
AND NOT T4.mrSTATUS="_Deleted_"
AND NOT T4.mrSTATUS="_SOLVED_"
AND NOT T4.mrSTATUS="_PENDING_SOLUTION_"
GROUP BY T1.mrID, T1.mrSEQUENCE, T1.mrUSERID, T1.mrFIELDNAME, T1.mrNEWFIELDVALUE, T1.mrOLDFIELDVALUE, T1.mrTIMESTAMP
ORDER BY T1.mrID, T1.mrTIMESTAMP;
Sincerely,
Kristopher

SQL: Selecting between date range

My query returns 1 value if I use the Max(SampleDateTime) or Min( ) on the Date/Time field I want, but it returns no values if I leave out the Max or Min. I want to return ALL the values, but I can't seem to figure this out.
I want all the Quality Samples between the Start and Stop times of a Production Run.
RunSamples:
Select Max([SampleDateTime])
FROM [QualitySamples] AS [GoodSamples]
WHERE [GoodSamples].[SampleDateTime] >= [ProductionRuns_tbl].[RunStartDate]
AND [GoodSamples].[SampleDateTime] <= [ProductionRuns_tbl].[RunEndDate]
ProductionRuns_tbl:
RunStartDate RunEndDate
1/1/2017 12 AM 1/5/17 12 AM
...
QualitySamples Tbl:
ID SampleDateTime
1 1/1/2017 2 am
2 1/1/2017 3 am
...
Here's the full SQL code:
SELECT ProductionRuns_tbl.RunName, ProductionRuns_tbl.RunStartDate,
ProductionRuns_tbl.RunEndDate,
(Select Max([SampleDateTime])
FROM [QualitySamples] AS [GoodSamples]
WHERE [GoodSamples].[SampleDateTime] >= [ProductionRuns_tbl].[RunStartDate]
AND [GoodSamples].[SampleDateTime] <= [ProductionRuns_tbl].[RunEndDate])
AS RunSamples
FROM ProductionRuns_tbl
WHERE (((ProductionRuns_tbl.RunName)=[Forms]![Home]![RunName]));
Try to use join instead:
SELECT ProductionRuns_tbl.RunName,
ProductionRuns_tbl.RunStartDate,
ProductionRuns_tbl.RunEndDate,
GoodSamples.SampleDateTime
FROM QualitySamples GoodSamples INNER JOIN ProductionRuns_tbl ON
GoodSamples.SampleDateTime >= ProductionRuns_tbl.RunStartDate AND
GoodSamples.SampleDateTime <= ProductionRuns_tbl.RunEndDate
WHERE ProductionRuns_tbl.RunName=[Forms]![Home]![RunName]
I'm taking a risk posting right now, because I had to try to read your mind on what you're trying to do (plus, I don't know if this will work in Access, but it will work in SQL server)
Since you want all the data, is this what you're looking for?
SELECT
ProductionRuns_tbl.RunName,
ProductionRuns_tbl.RunStartDate,
ProductionRuns_tbl.RunEndDate,
[QualitySamples].[SampleDateTime]
FROM
ProductionRuns_tbl
LEFT JOIN
[QualitySamples]
ON
[QualitySamples].[SampleDateTime] >= [ProductionRuns_tbl].[RunStartDate]
AND
[QualitySamples].[SampleDateTime] <= [ProductionRuns_tbl].[RunEndDate]
WHERE
(((ProductionRuns_tbl.RunName)=[Forms]![Home]![RunName]));
This should list the RunName, Start and End dates repeated for each individual SampleDateTime. Based on your more specific requirements, you can then refine the results from there.
Dont have WHERE, MAX or MIN. Just have the SELECT query.
Select [SampleDateTime]
FROM [QualitySamples] AS [GoodSamples]

Sql, how to get data in difference of 24 hours

Select p.uhid,p.inpatientno,dateof admission
from adt.inpatientmaster p
where p.uhid='apd1' and status <>0
Here uhid is unique. I want to check that a patient gets admitted in between 24 hours , here if patient gets admitted again then uhid remains same but inpatientno always change.
Ex:
Registraionno inpatientno dateofadmission
Apd1 xy1 18/01/15
Ap1 ab2 19/01/15
We can do arithmetic on Oracle dates. So yesterday is sysdate - 1.
You need to query the table twice. Once to find the patient records, and once to find any previous matches. Use a self-join to achieve this:
select p1.uhid,
p1.inpatientno as current_inpatientno,
p1.dateofadmission as current_dateofadmission
p2.inpatientno as previous_inpatientno,
p2.dateofadmission as previous_dateofadmission
from adt.inpatientmaster p1
join adt.inpatientmaster p2
on p2.uhid = p1.uhid
where p1.uhid='apd1'
and p1.status <> 0
and p2.dateofadmission >= p1.dateofadmission-1
and p2.inpatientno != p1.inpatientno
/
You may need to restrict on p2.status <> 0 as well: not sure what your business rules are.
This query will return one row for each match. If there are several admissions within the same 24 hours the result set will have one row for each combination.
SELECT p.uhid,
p.inpatientno,
p.dateofadmission
FROM adt.inpatientmaster p
WHERE p.status<>0
AND p.dateofadmission <= p.dateofadmission +1
AND p.uhid='APD1'

creating a sub-query

Sub-Query Help
I'm having a problem creating a sub-query (I think) and was hoping to get some guidance. Some things have been generalized for simplicity.
Select
A
b
c
d
e
Member ID
Hospital Admit Date
DRG Code
CLM_LN_SVC_FROM_DT
From
Claims Table
Where
DRG Code = 5
And A
And B
And c
I would like to take the result of this query specifically the Member ID and distinct Hospital Admit Dates for the Member and query against the claims table for all claims:
where Member ID in (result from above query) and at this point I need to pull claims in the range 30 days before the admit dates and up to 180 days after the admit date. This is where I'm struggling how to setup this sub query. Any brilliance beyond my limited base would be greatly appreciated...
It sounds you need something similar to following query:
Select Distinct
ClaPeriod.MemberId,
ClaPeriod.DRGCode,
ClaPeriod.ClaimDate,
ClaPeriod.AdmittedDate,
A,
B,
C,
D,
E
From Claims ClaMain,
Claims ClaPeriod
Where (ClaMain.MemberId, ClaMain.AdmittedDate) In (
Select MemberId, AdmittedDate
From Claims claId
Where DRGCode = 5
)
And ClaMain.MemberId = ClaPeriod.MemberId
And ClaPeriod.AdmittedDate >= ClaMain.AdmittedDate - 30
And ClaPeriod.DischargedDate <= ClaMain.AdmittedDate + 180
Order By ClaPeriod.MemberId, ClaPeriod.AdmittedDate
To be honest, I still am not sure I have fully understood your schema. I had to include a Distinct clause in my sql test to avoid duplicate results. If I missed the mark please tell me so and I will try to improve the answer.
UPDATE: Now that the schema is clearer for me as per OP's comments I will try to improve the answer.
As I understand it now, you need to get all claims that:
have the same MBR_ID as a claim with DRG=5.
have an HOSP_ADMT_DT (Admit Date) 30 days prior or before than the CLM_LN_SVC_FROM_DT (From_Date) of the DRG=5 claim.
have an HOSP_DSCHRG_DT (Discharge Date) at least 180 days after the CLM_LN_SVC_FROM_DT (From_Date) of the DRG=5 claim.
If it is so, it can be done with a query that joins the CLM_MED_DETL to itself. ne table would be to filter the claims with DRG=5 and the other to retrieve the claims that have the same MBR_ID and that comply with the date conditions. It would be a query like following:
Select CLAIMS.CLM_MED_DETL_ID,
CLAIMS.CLM_LN_CURR_STAT_TXT,
CLAIMS.CLM_ID_TXT,
CLAIMS.SVCG_PROV_NAME,
CLAIMS.SBMTD_DRG_CD,
CLAIMS.RVNU_CD,
CLAIMS.PLC_OF_SVC_CD,
CLAIMS.CLM_SRC_CD,
CLAIMS.CLM_LN_SEQ_NUM,
CLAIMS.CLM_LN_PRCDR_CD,
CLAIMS.MBR_ID,
CLAIMS.MBR_LST_NAME,
CLAIMS.MBR_FST_NAME,
CLAIMS.SVCG_PROV_ADDR_ZIP_CD,
CLAIMS.SVCG_PROV_ADDR_CNTY,
CLAIMS.HOSP_ADMT_DT,
CLAIMS.HOSP_DSCHRG_DT,
CLAIMS.CLM_LN_UNITS_NUM,
CLAIMS.CLM_LN_CHRG_AMT,
CLAIMS.CLM_LN_ALWD_AMT,
CLAIMS.CLM_LN_PD_AMT,
CLAIMS.TIN_TXT,
CLAIMS.CLM_LN_SVC_FROM_DT,
CLAIMS.CLM_LN_SVC_TO_DT
From CLM_MED_DETL DRG5CLAIMS,
CLM_MED_DETL CLAIMS
Where CLAIMS.MBR_ID = DRG5CLAIMS.MBR_ID
And DRG5CLAIMS.SBMTD_DRG_CD = '005'
And DRG5CLAIMS.CLM_LN_SVC_FROM_DT >= CLAIMS.HOSP_ADMT_DT - 30
And DRG5CLAIMS.CLM_LN_SVC_FROM_DT <= CLAIMS.HOSP_DSCHRG_DT + 180
And CLAIMS.CLM_SRC_CD = 'TRG_FA'
And CLAIMS.CLM_LN_PD_AMT <> 0
And CLAIMS.CLM_LN_CURR_STAT_TXT <> 91
Order By CLAIMS.MBR_LST_NAME Asc, CLAIMS.CLM_LN_SEQ_NUM Asc;

select query using multiple like conditions

Below is an existing ms sql server 2008 report query.
SELECT
number, batchtype, customer, systemmonth, systemyear, entered, comment, totalpaid
FROM
payhistory LEFT OUTER JOIN agency ON
payhistory.SendingID = agency.agencyid
WHERE
payhistory.batchtype LIKE 'p%' AND
payhistory.entered >= '2011-08-01 00:00:00.00' AND
payhistory.entered < '2011-08-15 00:00:00.00' AND
payhistory.systemmonth = 8 AND
payhistory.systemyear = 2011 AND
payhistory.comment NOT LIKE 'Elit%'
Results will look like this:
number batchtype customer systemmonth systemyear entered comment totalpaid
6255756 PC EMC1106 8 2011 12:00:00 AM DP From - NO CASH 33
5575317 PA ERS002 8 2011 12:00:00 AM MO-0051381526 7/31 20
6227031 PA FTS1104 8 2011 12:00:00 AM MO-10422682168 7/30 25
6232589 PC FTS1104 8 2011 12:00:00 AM DP From - NO CASH 103
2548281 PC WAP1001 8 2011 12:00:00 AM NCO DP $1,445.41 89.41
4544785 PCR WAP1001 8 2011 12:00:00 AM NCO DP $1,445.41 39
What I am trying to do is modify the query that will exclude records where the customer is like 'FTS%' and 'EMC%' and batchtype = 'PC'. As you can see in the result set there are records where customer is like FTS% and batchtype = 'PA'. I would like to keep these records in the results. I would appreciate any ideas offered.
Your query contains a mix of upper and lower string comparison targets. As far as I'm aware, SQL Server is not by default case-sensitive; is it possible this is what is tripping your query up? Check collation per this answer.
EDIT: Based on your updated question, can you not just use an AND clause that uses a NOT on the front?
In other words, add a 'AND not (x)' clause, where 'x' is the conditions that define the records you want to exclude? You'd need to nest the customer test, because it's an OR.
e.g.:
... payhistory.comment NOT LIKE 'Elit%'
AND not ((customer like 'FTS%' or customer like 'EMC%') AND batchtype = 'PC')
As a side note, I believe that a LIKE clause may imply an inefficient table scan in some (but not all) cases, so if this query will be used in a performance-sensitive role you may want to check the query plan, and optimise the table to suit.
$sql="select * from builder_property where builder_pro_name LIKE '%%' OR builder_pro_name LIKE '%za%' AND status='Active'";
This will return all the builder property name in table that will ends name like plaza or complex.
It can be because your sever might be case sensitive. In that case, below query would work.
SELECT
table1.number, table1.btype, table1.cust, table1.comment, table2.ACode
FROM
table1 LEFT OUTER JOIN table2 ON table1.1ID = table2.2ID
WHERE
lower(table1.btype) LIKE 'p%' AND
lower(table1.comment) NOT LIKE 'yyy%' AND
lower(table1.cust) NOT LIKE 'abc%' AND
lower(table1.cust) NOT LIKE 'xyz%' AND
lower(table1.btype) <> 'pc'
Add this condition to the WHERE clause:
NOT((customer LIKE 'FTS%' OR customer LIKE 'EMC%') AND batchtype='PC')
Assuming your other results are OK and you just want to filter those out, the whole query would be
SELECT
number, batchtype, customer, systemmonth, systemyear, entered, comment, totalpaid
FROM
payhistory
LEFT OUTER JOIN agency ON
payhistory.SendingID = agency.agencyid
WHERE
payhistory.batchtype LIKE 'p%' AND
payhistory.entered >= '2011-08-01 00:00:00.00' AND
payhistory.entered < '2011-08-15 00:00:00.00' AND
payhistory.systemmonth = 8 AND
payhistory.systemyear = 2011 AND
payhistory.comment NOT LIKE 'Elit%' AND
NOT((payhistory.customer LIKE 'FTS%' OR payhistory.customer LIKE 'EMC%') AND payhistory.batchtype='PC')
Hope that works for you.
When building complex where clauses it is a good idea to use parenthesis to keep everything straight. Also when using multiple NOT LIKE statements you have to combine all of the NOT LIKE conditions together using ORs and wrap them inside of a separate AND condition like this...
WHERE
(payhistory.batchtype LIKE 'p%')
AND (payhistory.entered >= '2011-08-01 00:00:00.00')
AND (payhistory.entered < '2011-08-15 00:00:00.00')
AND (payhistory.systemmonth = 8 )
AND (payhistory.systemyear = 2011)
AND ( // BEGIN NOT LIKE CODE
(payhistory.comment NOT LIKE 'Elit%')
OR (
(payhistory.customer NOT LIKE 'EMC%') AND
(payhistory.batchtype = 'PC')
)
OR (
(payhistory.customer NOT LIKE 'FTS%') AND
(payhistory.batchtype = 'PC')
)
) //END NOT LIKE CODE