SQL Count Where on a specific date... but the result is 0 - sql

Hi it is NOT my first time the i use this query:
SELECT COUNT(*) from dbo.SchDetail WHERE dbSchDate = '08-06-2020'
Query is working but he counts everytime 0.
But if i do a between "08-06-2020" and "07-06-2020".
I got the right result.
For mysql both query working fine.
But not on MSSQL.
I dont know what I do wrong.
Thanks for help

You are getting 0 because the WHERE clause filters out all rows. There are multiple reasons; for instance:
The table could be empty.
dbSchDate could be a datetime with a time component.
The constant may not be interpreted correctly as a date/time.
No values in the table might match.
I would suggest a proper date format, in YYYYMMDD format:
WHERE dbSchDate = '20200806'
You can also use:
WHERE dbSchDate >= '20200806'
dbSchDate < '20200807'
This version works even if there is a time component, as does:
WHERE CONVERT(DATE, dbSchDate) = '20200806'

Related

Sql Server Table date query showing incorrect result

I have a Sql server table which contains below Date values(4th october)
Now Below query is not showing any result
select
*
from [dbo].[TB_AUDIT] TBA
where TBA.ActionDate >= '10/01/2018' and TBA.ActionDate <= '10/04/2018' which is not correct.
But If I write
select
*
from [dbo].[TB_AUDIT] TBA
where TBA.ActionDate >= '10/01/2018' and TBA.ActionDate <= '10/05/2018' it is returning me all results.
What I am doing wrong.
There are two problems with this query. The first, is that it's using a localized string. To me, it looks like it's asking for rows between January and April. The unambiguous date format is YYYYMMDD. YYYY-MM-DD by itself may not work in SQL server as it's still affected by the language. The ODBC date literal, {d'YYYY-MM-DD'} also works unambiguously.
Second, the date parameters have no time which defaults to 00:00. The stored dates though have a time element which means they are outside the search range, even if the date parameter was recognized.
The query should change to :
select
*
from [dbo].[TB_AUDIT] TBA
where
cast(TBA.ActionDate as date) between '20181001' and '20181004'
or
cast(TBA.ActionDate as date) between {d'2018-10-01'} and {d'2018-10-04'}
Normally, applying a function to a field prevents the server from using any indexes. SQL Server is smart enough though to convert this to a query that covers the entire date, essentially similar to
where
TBA.ActionDate >='2018:10:01T00:00' and TBA.ActionDate <'2018-10-05T00:00:00'
When you don't specify a time component for a DATETIME, SQL Server defaults it to midnight. So in your first query, you're asking for all results <='2018-10-04T00:00:00.000'. All of the data points in your table are greater than '2018-10-04T00:00:00.000', so nothing is returned.
You want
TBA.ActionDate >= '2018-10-01T00:00:00.000' and TBA.ActionDate < '2018-10-05T00:00:00.000'`
Use properly formatted dates!
select *
from [dbo].[TB_AUDIT] TBA
where TBA.ActionDate >= '2018-10-01' and TBA.ActionDate <= '2018-10-04'
YYYY-MM-DD isn't just a good idea. It is the ISO standard for date formats, recognized by most databases.
when you just filter by the date, it is with regard to the time as per the standard.

Using GETDATE() to pull from a table

My apologies in advance for the basic (and probably silly) question.
I'm doing a SELECT query where I'm joining several tables. I have a table that contains a numeric value associated with certain days. What I would like to have in my output is the numeric value attached to today, but I'm clueless as to how to make this happen. Obviously, I would have the same value for every record in my output and I'm fine with that.
Is this even possible? If so, what would an example of the code be?
The table from which I would like the numeric value simply has dates in one column ([Calendar_Day]) and integers in another column ([X_Value]).
Below, you can see the last three lines of my SELECT statement. This latest attempt yielded NULL.
,[EnterpriseDB].[pcc].[conditions].Internal
,GETDATE() AS Date_Today
,(SELECT [X_Value] FROM [Analytics].[WorkArea].[Days_Vals] WHERE [Calendar_Day] = GETDATE()) AS BizVal_Today
Just guessing:
[Calendar_Day] is of the type date. While getdate() returns a datetime. That means the DBMS upcasts [Calendar_Day] to a datetime with a time of 00:00:00.0 in order to be able to compare the operands. But getdate() includes the current time. So unless you're executing the query at exactly 00:00:00.0 the values won't match and the subquery returns null.
To fix that, downcast getdate().
... WHERE [Calendar_Day] = convert(date, getdate()) ...
If [Calendar_Day] is also a datetime but you don't want to compare the hour (, minute, second ...) portion of it, downcast it as well.
... WHERE convert(date, [Calendar_Day]) = convert(date, getdate()) ...
Might throw any indexes out of the window though, if there are some on [Calendar_Day]. You might want to consider changing the data type to date or using a persistent, indexed computed column and compare against that, if that leads to any performance issues.

SQL Select Query on Date/Time column strange behavior

I am having an odd issue with a select statement in SQL Server Express, hopefully someone can shed some light on why I'm experiencing this behavior as well as the right way to do it.
When I run this query it returns exactly what I would expect:
SELECT
Action, TimeOccurred, UserName, IPv4From, ShareName,
FullFilePath, NewPathName, FromServer
FROM
File_System_Profiles
WHERE
Action LIKE '%create%'
AND (TimeOccurred >= '04/27/2017')
All those entries from 4/27 and anything after that.
When I run this query it returns 0 results which is extremely odd since there are entries for 4/27 in the previous query's results:
SELECT
Action, TimeOccurred, UserName, IPv4From, ShareName,
FullFilePath, NewPathName, FromServer
FROM
File_System_Profiles
WHERE
Action LIKE '%create%'
AND (TimeOccurred = '04/27/2017')
All I removed was the > between the = and the date and I get no results. I can clearly see when I run the first query that there are results where 04/27/2017 is the date that something occurred. If the first query didn't work I would assume there was a problem with my date format of MM/DD/YYYY and what is actually in the column YYYY-MM-DD HH:MM:SS but since the first one works it seems logical that the second one should.
It is a problem of the date format. As you mentioned, you are using Date format as "YYYY-MM-DD HH:MM:SS" so you should know that the value "04/27/2017" will be taken as "04/27/2017 00:00:00" when used in the comparison.
I assume that you have no record where the value in date field is "04/27/2017 00:00:00" and that is why when you use = operator, it does not match any record. However, the operator >= picks the records where hour:minute:second part of the date exist. As an example "04/27/2017 01:10:00" is greater than "04/27/2017 00:00:00" and therefore the > operator fetches those records.
Hope it helps.
First, always use ISO standard formats for comparison. Your code should look more like this:
where Action LIKE '%create%' AND
TimeOccurred = '2017-04-27'
Nauman explained the problem, which is the time component on TimeOccurred. You can solve this in various ways. One method is to convert to date. Something like this:
where Action LIKE '%create%' AND
cast(TimeOccurred as date) = '2017-04-27'
Depending on the database, the cast() might be replaced by trunc() or date_trunc() or something else.
However, I prefer this version:
where Action LIKE '%create%' AND
TimeOccurred >= '2017-04-27' AND
TimeOccurred < '2017-04-28'
It gets to the heart of the problem. And -- better yet -- SQL optimizers can make use of an index.

DateDiff in SQL ODBC

I'm using a datediff in SQL. It returns records when run directly in sql server 2008, but when I try and run it through ODBC it doesn't bring up an error, but it returns no rows.
SELECT mc_id, mc_date_entered,
COUNT([mv_value]) total
FROM MarkbookValue t1
RIGHT JOIN MarkbookColumn t2 ON t1.mv_column_id = t2.mc_id
WHERE mc_module_id = '703000026609358'
AND DateDiff(dd, mc_date_entered, '2012-10-05 20:00:00') = 0
AND mc_type = 'KEF'
AND mc_entered_by = 'A.ADMIN'
GROUP BY
mc_id, mc_date_entered;
Getting rid of the DateDiff lets the function run correctly, but I'd obviously like to have it in there. What am I doing wrong?
YYYY-MM-DD HH:MM:SS is not a safe date format to use for a date time literal value in SQL Server. Depending on SET DATEFORMAT your month and day part might be switched.
YYYY-MM-DDTHH:MM:SS and YYYYMMDD HH:MM:SS are safe to use regardless of SET DATEFORMAT.
To get the rows for a specific date I suggest that you do as in the answer provided by #RichardTheKiwi or if you are in SQL Server 2008 you can cast your column to date to remove the time part.
where cast(mc_date_entered as date) = '2012-10-05'
YYYY-MM-DD is safe for data type date.
I would almost always write dates in ISO-8601 format, the one without dashes being YYYYMMDD.
Just would like to also point out that if you want your query to use an index on mc_date_entered and remain SARGABLE, you'll want to rewrite it like this.
SELECT mc_id, mc_date_entered, COUNT([mv_value]) total
FROM MarkbookValue t1
RIGHT JOIN MarkbookColumn t2 ON t1.mv_column_id = t2.mc_id
WHERE mc_module_id = '703000026609358'
AND mc_date_entered >= '20121005'
AND mc_date_entered < '20121006'
AND mc_type = 'KEF'
AND mc_entered_by = 'A.ADMIN'
GROUP BY
mc_id, mc_date_entered;
Are you also aware that DATEDIFF(DD only considers the date portion, so there's really no point including the time (if we were still using DATEDIFF)?

XCODE - SQL Dates

I am trying to update my SQL DB when the the date has expired (i.e is less than now)
I have this lovely bit of SQL code
Update Notifications
SET Active = 'N'
where CAST(SetDate AS DATE) <= CAST('2012-08-23 11:19:00 +0000' AS DATE)
But it updates all the records (even if the date is not less than now)
I have also tried
Update Notifications
SET Active = 'N'
where CAST(SetDate AS DATE) < CAST('2012-08-23 11:19:00 +0000' AS DATE)
But this dosent affect any rows.
I guess I have something a little confused??
Any help???
Thanks
I cannot see anything odd about the code, except for this line:
CAST('2012-08-23 11:19:00 +0000' AS DATE)
If you are using CAST() to change it to the date, then there is no need to pass in the time portion of the value.
You did not provide the full table schema but one thing to consider is using a bit field for the Y/N values.
Here is a SQL Fiddle with the code working
Update Notifications
SET Active = 'N'
where CAST(SetDate AS DATE) <= CAST('2012-08-23' AS DATE)
One thing you have confused is types in SQL. I don't know what database you are using, but it probably has types for boolean (or int) and date. Storing booleans and dates as strings is very inefficient. For example, even if your example did work it would have to scan the entire database and cast each value in order to compare it.
The clue to the error is the < vs <=. This hints at the values being equal. If the cast fails on both sides, and returns the default value of zero, then then will be equal.
You should change your schema to use the correct types, then your query will work.