Access query won't work when dates have times - sql

I have a query stated:
select *
from tblClient
where IntakeDate = #5/31/2011#
I know for a fact there are 8 records that have that date. But none of records with that date are pulled by this query. Those 8 records have times as well as "short date" (e.g. "5/31/2011 1:42:00 PM")
As a test I set the date to exactly 5/31/2011 for one record, and the query will work for that one record. Clearly the time value is interfering with this query.
I do not want to change all the date data to a strict 'short date' format and would like to work with it as-is. Can anyone give me some idea how I can make this work?

Create a condition that encompasses a single day's time range:
select *
from tblClient
where IntakeDate >= #5/31/2011# AND < #6/1/2011#
[You could use the DateValue() function on your column, but that would prevent any index being used.]

The DateValue function truncates the time off the date
select *
from tblClient
where DateValue(IntakeDate) = #5/31/2011#

Related

Expanding SQL query for multiple dates

I have a SQL query that includes a __DATE__ macro. A Python script replaces this macro with the current date and then the statement is executed thus giving one day's worth of data.
For the first item selected, I would like to use tblLabTestResult.CollectionDate instead of __DATE__.
I would like to include the prior 7 days instead of just the current day.
The desired output would be something similar to:
Date,Result,Total
2021-08-28,Detected,5
2021-08-28,Not Detected,9
2021-08-29,Detected,23
2021-08-29,Not Detected,6
2021-08-30,Detected,88
2021-08-30,Not Detected,26
Current query:
SELECT
'__DATE__' as Date,
tblLabTestResult.Result as Result,
Count(tblLabTestResult.Result) as Total
FROM
PncRegDb.dbo.tblLabTestResult as tblLabTestResult
WHERE
tblLabTestResult.TestName like '%cov%'
AND tblLabTestResult.TestName not like '%aoe%'
AND tblLabTestResult.TestName not like '%antibody%'
AND tblLabTestResult.CollectionDate >= '__DATE__'
AND tblLabTestResult.CollectionDate <= '__DATE__ 11:59:59 PM'
GROUP BY
tblLabTestResult.Result;
How can I change my SQL query to accommodate these requirements? I am using MS SQL Server.
You can use DATEADD() function to get the date from 7 days ago and use all dates between date-7days and date. I have updated where condition in your query below:
SELECT
'__DATE__' as Date,
tblLabTestResult.Result as Result,
Count(tblLabTestResult.Result) as Total
FROM
PncRegDb.dbo.tblLabTestResult as tblLabTestResult
WHERE
tblLabTestResult.TestName like '%cov%'
AND tblLabTestResult.TestName not like '%aoe%'
AND tblLabTestResult.TestName not like '%antibody%'
AND tblLabTestResult.CollectionDate between DATEADD(day, -7, '__DATE__') and '__DATE__ 11:59:59 PM'
GROUP BY
tblLabTestResult.Result;
A few points:
Columns that are not aggregated must be in the GROUP BY
You should be passing your date as a parameter
Best to use a half-open interval to compare dates (exclusive end-point), so #endDate is the day after the one you want
Use short, meaningful aliases to make your code more readable
It doesn't make sense to group and aggregate by the same column. If Result is a non-nullable column then Count(Result) is the same as Count(*)
If you want to group by whole days (and CollectionDate has a time component) then replace ltr.CollectionDate with CAST(ltr.CollectionDate AS date) in both the SELECT and GROUP BY
SELECT
ltr.CollectionDate as Date,
ltr.Result as Result,
COUNT(*) as Total
FROM
PncRegDb.dbo.tblLabTestResult as tblLabTestResult
WHERE
ltr.TestName like '%cov%'
AND ltr.TestName not like '%aoe%'
AND ltr.TestName not like '%antibody%'
AND ltr.CollectionDate >= #startdate
AND ltr.CollectionDate < #endDate
GROUP BY
ltr.CollectionDate, ltr.Result;

Fetching records from SQL based on Month name

So this my table structure and data.
Now I want to filter data based on Month by ExpenseDate column.
So how can I achieve that?
I was trying
select * from tblExpenses where (ExpenseDate = MONTH('April'))
But it throws an error: "Conversion failed when converting date and/or time from character string."
Please help. Thank you.
You are putting month() on the wrong column. It can be applied to ExpensesDate:
select *
from tblExpenses
where month(ExpenseDate) = 4;
Note that month() returns a number, not the name of the month.
I think it is more likely that you want records from a particular April, not every April. This would be expressed as:
where ExpenseDate >= '2018-04-01' and ExpenseDate < '2018-05-01'
I think your where clause is just reversed I think you want this (and change the word to a number)
select * from tblExpenses where Month(ExpenseDate) = 4

Select Query between dates not retrieving any data

I have been trying to retrieve the rows registered between two dates (since every time a person goes through a door a row is inserted). This way we get the "amount of visitors" on a monthly basis.
When querying the following:
select MOV_DATAHORA from LOG_CREDENCIAL
WHERE MOV_DATAHORA>'2017-01-01'`
a total of 5851 rows are shown. This is an example of a row:
2017-01-05 21:33:30.000
However when trying the following:
select MOV_DATAHORA from LOG_CREDENCIAL
WHERE MOV_DATAHORA>'2017-01-01'
AND MOV_DATAHORA<'2017-01-02'
0 rows are shown. I even tried the count(MOV_DATAHORA) statement but it still isn't working. I also tried with the BETWEEN statement unsuccessfully. Any ideas why?
Well... the simplest explanation based on your query predicate:
WHERE MOV_DATAHORA > '2017-01-01'
AND MOV_DATAHORA < '2017-01-02'
is that on January 1st (right after the New years) there were no visitors.
You are comparing a DateTime and a Date data types. Your table has a DateTime as you can see the 21:33:30.000 after the date, to convert and compare like types do the following.
SELECT MOV_DATAHORA FROM LOG_CREDENCIAL WHERE DATE(MOV_DATAHORA)>'2017-01-01'
AND DATE(MOV_DATAHORA)<'2017-01-02'
or using between
SELECT MOV_DATAHORA FROM LOG_CREDENCIAL WHERE DATE(MOV_DATAHORA) BETWEEN '2017-01-01'
AND '2017-01-02'

Giving the wrong records when used datetime parameter in MS Access Query

I am working MS-Access 2007 DB .
I am trying to write the query for the Datetime, I want to get records between 14 December and 16 December so I write the bellow query.
SELECT * FROM Expense WHERE CreatedDate > #14-Dec-15# and CreatedDate < #16-Dec-15#
( I have to use the two dates for the query.)
But It returning the records having CreatedDate is 14 December...
Whats wrong with the query ?
As #vkp mentions in the comments, there is a time part to a date as well. If it is not defined it defaults to midnight (00:00:00). As 14-dec-2015 6:46:56 is after 14-dec-2015 00:00:00 it is included in the result set. You can use >= 15-dec-15 to get around this, as it will also include records from 15-dec-2015. Same goes for the end date.
It seems you want only records from Dec 15th regardless of the time of day stored in CreatedDate. If so, this query should give you what you want with excellent performance assuming an index on CreatedDate ...
SELECT *
FROM Expense
WHERE CreatedDate >= #2015-12-15# and CreatedDate < #2015-12-16#;
Beware of applying functions to your target field in the WHERE criterion ... such as CDATE(INT(CreatedDate)). Although logically correct, it would force a full table scan. That might not be a problem if your Expense table contains only a few rows. But for a huge table, you really should try to avoid a full table scan.
You must inlcude the time in your thinking:
EDIT: I wrote this with the misunderstanding, that you wanted to
include data rows from 14th to 16th of Dec (three full days).
If you'd write <#17-Dec-15# it would be the full 16th. Or you'd have to write <=#16-Dec-15 23:59:59#.
A DateTime on the 16th of December with a TimePart of let's say 12:30 is bigger than #16-Dec-15#...
Just some backgorund: In Ms-Access a DateTime is stored as a day's number and a fraction part for the time. 0.5 is midday, 0.25 is 6 in the morning...
Comparing DateTime values means to compare Double-values in reality.
Just add one day to your end date and exclude this:
SELECT * FROM Expense WHERE CreatedDate >= #2015/12/14# AND CreatedDate < #2015/12/17#
Thanks A Lot guys for your help...
I finally ended with the solution given by Darren Bartrup-Cook and Gustav ....
My previous query was....
SELECT * FROM Expense WHERE CreatedDate > #14-Dec-15# and CreatedDate < #16-Dec-15#
And the New working query is...
SELECT * FROM Expense WHERE CDATE(INT(CreatedDate)) > #14-Dec-15# and CDATE(INT(CreatedDate)) < #16-Dec-15#

ColdFusion query four days ago

I want to query order information from 4 days ago. I cannot quite get the query to use the full 24hours of the day though:
<cfquery name="rsByDate" datasource="#request.dsn#">
SELECT tbl_customers.cst_FirstName
, tbl_customers.cst_LastName
, tbl_customers.cst_Email
, tbl_orders.order_ID
, tbl_orders.order_Date
FROM tbl_customers INNER JOIN tbl_orders
ON tbl_customers.cst_ID = tbl_orders.order_CustomerID
WHERE tbl_orders.order_Date >= #CreateODBCDateTime(DateAdd("d",-5,Now()))#
AND tbl_orders.order_Date <= #CreateODBCDateTime(DateAdd("d",-4,Now()))#
AND order_Status = 3
ORDER BY tbl_orders.order_Date DESC
</cfquery>
What I'm hoping to achieve is to perform this query and then use cfmail to ask the customers to review us four days after their order is marked as status 3 'shipped'.
I think I have the date settings not quite right. Where am I going wrong?
It's because you're basing your filter dates on now(), which has a time component. So now()-4 for me is 5/11/2012, but at 12:10pm. You only want to use the date part for the filter.
You should never hard-code your dynamic values in your SQL string anyhow, so firstly use <cfqueryparam> to parameterise your dynamic values, and then use a CF_SQL_DATE as the type, which should only pass the date through, not the date/time. I am not in a position to test this for you at the moment, but try that... if it still passes the time part of the date/time, then create a date object with just the date part, using createDate().