Search date from SQL database from longer than one year ago - sql

I have a SQL Database varchar field which is called date_finish. This field has been setup as a varchar(50). The format of the date is set out like this: 07/06/2017 dd/mm/yyyy.
I'm trying to search the database for all dates over 1 year old using this statement:
SELECT CONVERT(datetime, date_finish, 103) AS DB_DATE, booking_code, cust_id, status
FROM repair_details
WHERE (date_finish > DATEADD(year, - 1, GETDATE()))
ORDER BY DB_DATE
There are some fields that are blank, cust_id is 0 and status aren't complete, so I added:
(date_finish <> '') AND (status = 'COMPLETE') AND (cust_id <> '0')
to the above statement.
In all cases I get an error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
What am I doing wrong???

Convert to a date using an explicit format:
WHERE CONVERT(date, date_finish, 103) > DATEADD(year, - 1, GETDATE())
Obviously, this gets dates since one year ago -- based on your code. If you want older dates, then use < rather than >.
Then, fix the data! You should be storing date/time values using proper types. One method is:
update repair_details
set date_finish = CONVERT(date, date_finish, 103); -- sets to default date format on system
alter repair_details alter date_finish date;

You haven't done the date conversion in the WHERE clause - it is comparing a string to a date there.

The error is because, when the column date_finish appears to be null. As such, you need to have a condition:
((date_finish IS NOT NULL ) AND
(date_finish <> '' ) ) AND
(status = 'COMPLETE' ) AND
(cust_id <> '0' )

Related

Converting date format of column in sql server

I'm trying to change the date format of data in column, that is had been inserted in this format
dd/mm/yyyy. I wanna change to this format yyyy-MM-dd in select statement.
I've tried by this query :
select CONVERT(nvarchar,cast(date1 as DATE),23) from Table1
On first two second I getting the result correctly then this Error appear:
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
If you have inserted the value as a string, then you need to convert from that format. For the one you specify, you can try:
convert(date, datecol, 103)
Next, if the column is already a date, then your SQL Server settings might be controlling how the data is displayed. In this case, you can add a computed column for the format you want:
alter table t add datecol_yyyymmdd as (convert(varchar(10), datecol, 120));
If the column is a string and you want to convert the format, first check to see if all the values are as you expect. To return bad values:
select datecol
from t
where try_convert(date, datecol, 103) is null and datecol is not null;
If all are fine, then you can use:
update t
set datecol = convert(varchar(10), convert(date, datecol, 103), 120);
You can then alter the type to be a date.

Handling a value of zero in a date datatype

I'm reporting out of a database that is using decimal(17,6) as the datatype for a date field. For example, the current date/time in this field would be 20210820.171900. Unusual, but whatever. I need to convert the original date field from decimal(17,6) to datetime. This is what I have:
SELECT convert(datetime, convert(varchar,convert(int, lastmoddatetime)), 0)
from Table1
The above statement works correctly as long as none of the records have a value of zero in this column. Unfortunately, the column value defaults to zero (0.000000) if no date has been calculated for it. Whenever a column has a zero value, I get the following error:
Conversion failed when converting date from character string.
How can I overcome this issue? Ultimately, I'm needing to apply a dateadd function to the lastmoddatetime field.
Note: Before you suggest changing the column definition, this database originated in the 1990's and I'm not allowed to make any changes to the database structure.
You can use NULLIF to null out those values
convert(datetime, convert(varchar(15), convert(int, NULLIF(lastmoddatetime, 0.0))), 0)
Either use TRY_CONVERT or CASE - depending how you want to handle the zero case.
SELECT
-- If desiring null for 0 and SQL Server 2012+
TRY_CONVERT(date, CONVERT(varchar, CONVERT(int, lastmoddatetime)), 0)
, CASE WHEN lastmoddatetime <> 0
-- If desiring some other valid date or < SQL Server 2012
THEN CONVERT(date, CONVERT(varchar, CONVERT(int, lastmoddatetime)), 0)
ELSE NULL /* Whatever valid datetime value you want */ END
FROM (
VALUES (20210820.171900), (0.0)
) x (lastmoddatetime);
I note that this ignores the time component - so am converting to a date not datetime above. If you need to handle the time component you need to update your question.
Yet another option.
You can thin it out a bit by using left() and try_convert()
Example
Declare #YourTable table (lastmoddatetime numeric(17,6))
Insert into #YourTable values
(20210820.171900)
,(0.0)
Select AsDate = try_convert(date,left(lastmoddatetime,8))
,AsDateTime = try_convert(datetime,left(lastmoddatetime,8))
From #YourTable
Results
AsDate AsDateTime
2021-08-20 2021-08-20 00:00:00.000
NULL NULL
use
convert(datetime,convert(int,lastmoddatetime),0)

SQL Server: Inconsistencies in date

create table #temp
(
A date
)
insert into #temp(A)
values(GETDATE())
insert into #temp(A)
values(GETDATE()-1)
Now when I query the table as
select A from #temp where A>=GETDATE() and A<=GETDATE()
I get no records
But GETDATE() record value should satisfy my where condition, shouldn't it at least pass me one record?
Please guide me if I am missing some point here.
You need to do conversion, so it seems :
where a >= convert(date, dateadd(day, -1, getdate())) and
a <= convert(date, getdate());
Your where clause comparing date as :
where a >= '2020-04-21 16:01:27.277' and a <= '2020-04-21 16:01:27.277'
So, you need to convert date because getdate()will also return time portions.
Since your where clause looks for single day so you can do :
where a = convert(date, getdate())
Yogesh is right.
GETDATE() gives the present DATEIME value. When you insert it into a DATE column, SQL Server coerces -- silently typecasts -- the DATETIME to a DATE before inserting it.
But when you use it in a WHERE clause, SQL Server coerces the DATE from your column into a DATETIME value by turning 2020-04-20 into 2020-04-20 00:00:00. That can't be the same as GETDATE() except during the first few milliseconds of each day. (Meaning you or your test krewe are extremely unlikely to catch it equal.)

Converting date and/or time from character string is failing

I have this query and I tried converting it to every format, I mean the date time etc but it doesn't work and throws error:
Conversion failed when converting date and/or time from character string.
SELECT W.Organization_ID,
W.NIT_No,
W.SchemeID,
OpeningDate,
OpeningTime,
GETDATE(),
WorkNo,
CONVERT(decimal(10, 2), W.Cost) AS Cost,
WorkName,
W.ExpiryDate as ExpiryDate,
CONVERT(VARCHAR,OpeningDate,106),
CASE WHEN
CONVERT(DATETIME, CONVERT(VARCHAR(20),OpeningDate,106) + ' '
+ CONVERT(VARCHAR(20),OpeningTime,108))< GETDATE()
THEN 1
ELSE 0 END AS OpeningVaild
FROM Works W
the CASE part throws error.
OpeningDate is of type Varchar and OpeningTime is of type Time.
Why?
You are converting just a TIME datatype not a DATETIME so you don't need to specify the style:
DECLARE #T TIME = '08:05:06';
SELECT CONVERT(VARCHAR(8), #T) AS [Time];
SELECT CAST(#T AS VARCHAR(8)) AS [Time];
Or since you are using CONVERT()pick the right style for TIME datatype which is 108 or 114, instead of 106
SELECT CONVERT(VARCHAR(8), #T, 108) AS [Time];
Update:
According to the error Msg, your problem is in the CASE part.
That because you are trying to concat a DATETIME with a VARCHAR datatype, look at here to what you'r converting:
CASE WHEN
CONVERT(DATETIME, CONVERT(VARCHAR(20),OpeningDate,106) + ' '
+ CONVERT(VARCHAR(20),OpeningTime,108))< GETDATE()
THEN 1
ELSE 0 END AS OpeningVaild
Also the column OpeningDate -according to the error Msg- is VARCHAR so your are convert a VARCHAR to VARCHAR then convert it again to DATETIME then you try to concatinate the DATETIME with the VARCHAR returned from converting OpeningTime column from TIMEto VARCHAR, then try to compare them with GETDATE() which is DATETIME datatype.
So you CASE should look like:
CASE WHEN
(
CAST(OpeningDate AS DATETIME) + -- VARCHAR to DATETIME
CAST(OpeningTime AS DATETIME) -- TIME to DATETIME
) < GETDATE()
THEN 1
ELSE 0 END AS OpeningVaild
A beside note, here in this line
CONVERT(VARCHAR,OpeningDate,106),
You are trying to convert a VARCHAR to VARCHAR and without specify the lenght too, so this line should be:
CONVERT(VARCHAR(10),CAST(OpeningDate AS DATE),106),
Finally, don't ever ever store DATE as VARCHAR, the DATE/ TIME/ DATEIME are there for a reason, so use them and all other datatypes wisely.
Here is a demo represent your issue, and how to fix it.
You can simplify this big time by changing the expression a little.
This way you don't have to convert and concatenate.
SELECT
CASE WHEN OpeningDate < GETDATE() - OpeningTime
THEN 1
ELSE 0 END AS OpeningVaild
Note I am assuming that Openingdate has the format dd-mon-yyyy. Otherwise you still need to convert it, but still shorter:
SELECT
CASE WHEN Convert(date, OpeningDate, 106) < GETDATE() - OpeningTime
THEN 1
ELSE 0 END AS OpeningVaild
So I understand the problem is with this part:
CASE WHEN CONVERT(DATETIME, CONVERT(VARCHAR(20),OpeningDate,106) + ' ' + CONVERT(VARCHAR(20),OpeningTime,108))< GETDATE() THEN 1 ELSE 0 END AS OpeningVaild
Update
Since I've first posted my answer it turns out that you store the opening date as varchar instead of date.
First, you should stop doing that. Never store dates in anything other than a Date column (unless you need them with time as well, and then use DateTime2).
For more information, read Aaron Bertrand's Bad habits to kick : choosing the wrong data type.
Assuming the data type of the column can't change, you wrote in the comments to the question:
#ZoharPeled: this is the format of openingdate 2017-04-10
Illustrating one of the problems caused by storing dates as strings - How can I, or anyone else for that matter, know if that's the 10th of April or the 4th of October? The answer is we can't.
So, assuming it's the 10th of April, you can convert it to DateTime using convert with 126 as the style parameter:
CASE
WHEN CONVERT(DateTime, OpeningDate, 126) + CAST(OpeningTime As DateTime) < GETDATE() THEN
1
ELSE
0
END As OpeningVaild
First version:
Assuming that the data type of OpeningDate is Date and the data type of OpeningTime is Time, Seems like you are attempting to figure out if these columns combination into a DateTime is before the current DateTime.
Instead of converting them into strings and back to DateTime, you can cast both to DateTime and simply add them together:
CASE
WHEN CAST(OpeningDate As DateTime) + CAST(OpeningTime As DateTime) < GETDATE() THEN
1
ELSE
0
END As OpeningVaild
Another option would be to use GETDATE() twice. I don't think it should matter in the select clause, but in the where clause it's important to use this option since the first one will make these columns non-seargable, meaning the database engine will not be able to use any indexes that might help the execution plan of the statement:
CASE
WHEN OpeningDate < CAST(GETDATE() AS DATE)
OR
(
OpeningDate = CAST(GETDATE() AS DATE)
AND OpeningTime <= CAST(GETDATE() AS TIME)
) THEN
1
ELSE
0
END AS OpeningVaild
That being said, your query also have CONVERT(VARCHAR,OpeningDate,106) - The 106 style returns a string representation of the date as dd mon yyyy - meaning 11 chars - so change that to CONVERT(CHAR(11),OpeningDate,106) Note that using varchar without specifying the length defaults to 30, which is not a problem in this case since it's more than he 11 chars you need, but it's a bad habit to not specify length and you should kick it.

Conversion of a varchar data type to a datetime data type resulted in an out-of-range value in SQL query

I have a table with a column that stores the date and time. I need to write a query to get only the date from that column,
SELECT CAST(CONVERT(VARCHAR, LoginTime, 101) AS datetime) FROM AuditTrail
But, when I run the query I am getting this error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
the data in the column is datetime ex: 2012-06-18 12:08:04.000
so i need to extract the date only and remove the time
note that the [Logintime] column is datatime format
Try ISDATE() function in SQL Server. If 1, select valid date. If 0 selects invalid dates.
SELECT cast(CONVERT(varchar, LoginTime, 101) as datetime)
FROM AuditTrail
WHERE ISDATE(LoginTime) = 1
Click here to view result
EDIT :
As per your update i need to extract the date only and remove the time, then you could simply use the inner CONVERT
SELECT CONVERT(VARCHAR, LoginTime, 101) FROM AuditTrail
or
SELECT LEFT(LoginTime,10) FROM AuditTrail
EDIT 2 :
The major reason for the error will be in your date in WHERE clause.ie,
SELECT cast(CONVERT(varchar, LoginTime, 101) as datetime)
FROM AuditTrail
where CAST(CONVERT(VARCHAR, LoginTime, 101) AS DATE) <=
CAST('06/18/2012' AS DATE)
will be different from
SELECT cast(CONVERT(varchar, LoginTime, 101) as datetime)
FROM AuditTrail
where CAST(CONVERT(VARCHAR, LoginTime, 101) AS DATE) <=
CAST('18/06/2012' AS DATE)
CONCLUSION
In EDIT 2 the first query tries to filter in mm/dd/yyyy format, while the second query tries to filter in dd/mm/yyyy format. Either of them will fail and throws error
The conversion of a varchar data type to a datetime data type resulted
in an out-of-range value.
So please make sure to filter date either with mm/dd/yyyy or with dd/mm/yyyy format, whichever works in your db.
hope this may help you:
SELECT CAST(LoginTime AS DATE)
FROM AuditTrail
If you want to have some filters over this datetime or it's different parts, you can use built-in functions such as Year and Month
as you can see on the answer to this question:
Conversion of a varchar data type to a datetime data type resulted in an out-of-range value
-- set the dateformat for the current session
set dateformat dmy
-- The conversion of a varchar data type
-- to a datetime data type resulted in an out-of-range value.
select cast('2017-08-13 16:31:31' as datetime)
-- get the current session date_format
select date_format
from sys.dm_exec_sessions
where session_id = ##spid
-- set the dateformat for the current session
set dateformat ymd
-- this should work
select cast('2017-08-13 16:31:31' as datetime)
I struggled with the same problem. I have stored dates in SQL Server with format 'YYYY-MM-DD HH:NN:SS' for about 20 years, but today that was not able anymore from a C# solution using OleDbCommand and a UPDATE query.
The solution to my problem was to remove the hyphen - in the format, so the resulting formatting is now 'YYYYMMDD HH:MM:SS'. I have no idea why my previous formatting not works anymore, but I suspect there is something to do with some Windows updates for ADO.
some problem, but I find the solution, this is :
2 February Feb 28 (29 in leap years)
this is my code
public string GetCountArchiveByMonth(int iii)
{
// iii: is number of months, use any number other than (**2**)
con.Open();
SqlCommand cmd10 = con.CreateCommand();
cmd10.CommandType = CommandType.Text;
cmd10.CommandText = "select count(id_post) from posts where dateadded between CONVERT(VARCHAR, #start, 103) and CONVERT(VARCHAR, #end, 103)";
cmd10.Parameters.AddWithValue("#start", "" + iii + "/01/2019");
cmd10.Parameters.AddWithValue("#end", "" + iii + "/30/2019");
string result = cmd10.ExecuteScalar().ToString();
con.Close();
return result;
}
now for test
lbl1.Text = GetCountArchiveByMonth(**7**).ToString(); // here use any number other than (**2**)
**
because of check **February** is maxed 28 days,
**