My table name as tbl_event
Event_ExpiryDate, Event_Date fields data type is varchar, I have using the following query for getting data from the table:
select * from tbl_event
WHERE
LEFT (CONVERT(VARCHAR,Event_ExpiryDate,103),12)>= LEFT(CONVERT(varchar,GetDate(),103),12) and
LEFT (CONVERT(VARCHAR,Event_Date,103),12)<= LEFT(CONVERT(varchar,GetDate(),103),12)
but I am getting a result like this
1 data to be missing. Why? this issue only on some month's date only. Months are 2,4,8,12
The real problem here is your data, and that you're using the wrong data type. Fix the data type, fix the problem.
You can fix that by firstly changing your varchar representation of a date to an unambiguous Date format, yyyyMMdd (This assumes your dates are in the format dd/MM/yyyy):
UPDATE dbo.tbl_event
SET Event_Date = CONVERT(varchar(8),CONVERT(date,Event_Date,103),112),
Created_Date = CONVERT(varchar(8),CONVERT(date,Created_Date,103),112),
Event_ExpiryDate = CONVERT(varchar(8),CONVERT(date,Event_ExpiryDate,103),112);
Then you can ALTER the table to fix your data types:
ALTER TABLE dbo.tbl_event ALTER COLUMN Event_Date date NULL; --Use NOT NULL if not NULLable
ALTER TABLE dbo.tbl_event ALTER COLUMN Created_Date date NULL; --Use NOT NULL if not NULLable
ALTER TABLE dbo.tbl_event ALTER COLUMN Event_ExpiryDate date NULL; --Use NOT NULL if not NULLable
Note: If any of your dates have bad values, for example '31/04/2019', the above will fail. You can get around this by changing the CONVERT functions to TRY_CONVERT, however any values that fail to convert will have the value NULL. If your columns have the NOT NULL property you will need to ensure you handle that too. If you do have bad values in your table, I strongly suggest taking a backup, or copy of the database/table first, so that you have a historical copy. (Of course, does a date like '31/04/2019' or '12/13/2018' have any meaning anyway?)
You can use only convert() :
where convert(date, Event_ExpiryDate, 103) >= convert(date, getdate()) and
convert(date, Event_Date, 103) <= convert(date, getdate());
However, storing varchar date is really bad idea. It will lead you lots of in trouble.
Related
I have one date columns as varchar datatype which has multiple date formats. I have to convert all different formats into one date format as 'YYYY-MM-DD'.
I am trying to convert it but couldn't make it. Below are different formats available in column.
Input
8/15/2022
15-Aug-22
15/08/2022
Required Output
2022-08-15
Honestly, I think you need to take the pessimistic approach here and assume that, possibly for a lot of your data, you don't know what the value is meant to be. As I stated in the comments, if you have the value '01/12/2021' is that 1 December 2021 or 12 January 2021, how do you know, and more importantly how would SQL Server know? As such, for dates like this you don't know and therefore the value NULL is more appropriate that a guess.
Here I use 3 different formats, an implicit one, and then 2 explicit ones (MM/dd/yyyy and dd/MM/yyyy) Then I check if the MIN and MAX values match (NULL values are ignored for aggregation), and if they do return that value. If they don't then NULL, as what value the date is is ambiguous and therefore intentionally shown as an unknown value (NULL):
You can, if needed, add more styles to the below, but this should be enough for you to work with.
CREATE TABLE dbo.YourTable (ID int IDENTITY(1,1), --I assume you have a unique identifier
StringDate varchar(20));
INSERT INTO dbo.YourTable (StringDate)
VALUES('8/15/2022'), --Must be M/d/yyyy
('15-Aug-22'),
('15/08/2022'), --Must be dd/MM/yyyy
('12/01/2021'); --Could be MM/dd/yyyy or dd/MM/yyyy
GO
SELECT YT.ID,
YT.StringDate,
CASE MAX(V.SomeDate) WHEN MIN(V.SomeDate) THEN MAX(V.SomeDate) END AS DateDate
FROM dbo.YourTable YT
CROSS APPLY (VALUES(TRY_CONVERT(date,YT.StringDate)), --Implicit conversion
(TRY_CONVERT(date,YT.StringDate,101)), --US style MM/dd/yyyy
(TRY_CONVERT(date,YT.StringDate,103)))V(SomeDate) --UK style dd/MM/yyyy
GROUP BY YT.ID,
YT.StringDate;
GO
DROP TABLE dbo.YourTable;
db<>fiddle
You can use a combination of TRY_CONVERT and REPLACE function in a CASE operator to do so.
As an example :
DECLARE #T TABLE(STR_DATE VARCHAR(32));
INSERT INTO #T VALUES
('8/15/2022'),
('15-Aug-22'),
('15/08/2022');
SELECT CASE
WHEN TRY_CONVERT(DATE, STR_DATE, 101) IS NOT NULL
THEN CONVERT(DATE, STR_DATE, 101)
WHEN TRY_CONVERT(DATE, REPLACE(STR_DATE, '-', ' '), 6) IS NOT NULL
THEN CONVERT(DATE, REPLACE(STR_DATE, '-', ' '), 6)
WHEN TRY_CONVERT(DATE, STR_DATE, 103) IS NOT NULL
THEN CONVERT(DATE, STR_DATE, 103)
END
FROM #T
I have problem with converting date from varchar to date format:
Msg 241, Level 16, State 1, Line 15
Conversion failed when converting date and/or time from character string.
I'm trying to convert/cast it like SELECT convert(DATE, '25.02.2019');. Can't change string order bacause the data are from existing table.
I know that the solution is easy but I'm still missing something and didn't get it yet :(
If you are unable to fix the underlying problem (that the table uses the wrong data type), you need to apply the correct DATETIME Style, which for dd.MM.yyyy is 104:
SELECT CONVERT(DATE, '25.02.2019', 104);
If at all possible though you should correct the original table. You should never store dates using VARCHAR, there is not one good reason to do so, and lots of good reasons not to. It will save you a lot of headaches if you change your datatype to DATE and then you won't have to worry about conversion errors. The longer you leave it the worse it will get. If you can't change the table, have a word with your DBA, and tell them to change the table. If you don't have a DBA, find someone who can.
Some good articles on this below:
Bad habits to kick : choosing the wrong data type
Bad habits to kick : mis-handling date / range queries
ADDENDUM
If you are unable to change the actual column because it is used by other processes, you can still sanitise the column by using a check contraint, and optionally include a computed column so you always have access to a real date, and not a varchar:
e.g.
IF OBJECT_ID(N'tempdb..#DateTest', 'U') IS NOT NULL
DROP TABLE #DateTest;
CREATE TABLE #DateTest
(
StringDate CHAR(10) NOT NULL,
RealDate AS CONVERT(DATE, StringDate, 104),
CONSTRAINT CHK_DateTest__RealDate CHECK (TRY_CONVERT(DATE, StringDate, 104) IS NOT NULL)
);
This will allow you to continue to add/edit varchar dates:
-- insert valid date and check output
INSERT #DateTest (StringDate) VALUES ('25.02.2019');
SELECT RealDate
FROM #DateTest;
The check constraint will prevent you from adding any dates that are not dates:
--Try to insert invalid date
INSERT #DateTest (StringDate) VALUES ('29.02.2019');
This will throw an error:
The INSERT statement conflicted with the CHECK constraint "CHK_DateTest__RealDate". The conflict occurred in database "tempdb", table "dbo.#DateTest___________________________________________________________________________________________________________000000000704", column 'StringDate'.
You can even index the column:
CREATE NONCLUSTERED INDEX IX_DateTEst ON #DateTest (RealDate);
With the index on you can take advantage of the benefits storing dates properly gives.
Your string is in the wrong format.
Should be:
SELECT convert(DATE, '2019-05-02')
Edit: If you can't get the date in that format, put 104 as a third argument.
Here's a list of the optional format arguments. https://www.w3schools.com/SQL/func_sqlserver_convert.asp
I have a view where I Select about 100 rows to allow users to easily query data. In this data, I have a field that is sometimes a date and sometimes text. A date or text depends on type. I cast to a date value like so.
SELECT Cast(Value as Date) as column
from Table
Where type = 1
When you then try to run a query against this column, you get a Conversion failed when converting date and/or time from character string. Here is the query.
SELECT Column
From View
WHERE Column BETWEEN '01/01/2015' AND '12/31/2015'
I have another field that is a date and if I replace it in this query, the query works. Likewise the data from the whole table will load. Any ideas are appreciated. Thanks
Basically, I need this Query to work and not give me the error described above.
select cast(value as date)
from Value
where type = 1
and cast(value as date) between '01/01/2015' and '12/31/2015'
My guess is that you have entries in that column that cannot be converted to datetime. You may be able to find them by running
Select * from table where isdate(value) = 0
I have a very simple query. (I'm working in SQL Server 2008.) I'm trying to select all records from a view where their ModifiedOn column is greater than a specified date. The ModifiedOn column is a datetime format. So, I have:
DECLARE #date1 AS datetime = '2013-07-31 24.59.59.999'
SELECT
some_column
FROM dbo.some_view
WHERE ModifiedOn > #date1
SQL is throwing the following error, though:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value. Why is SQL thinking that one of my dates is a varchar, when I know that both of them are datetime formats? How do I fix it?
Datetime variable expects data to be in format of
YYYY-MM-DD HH:MM:SS.mmm
In your case you are trying to assign a value which is not a valid time. HH.MM.SS.mmm
Secondly a clock never strikes 24:00:00 it goes from 23:59:59.999 to 00:00:00.001.
Also in your case rather than juggling with seconds and milliseconds. just use date value and use the ANSI standard YYYYMMDD which is also sargable.
You could have written your above query something like
SELECT some_column
FROM dbo.some_view
WHERE ModifiedOn >= '20130801'
I have a column BirthDate in a table that is using the datetime data type. Currently, the values resemble the format 1987-12-30 00:00:00.000.
I would like to update all the rows of this table, changing them to the following format with the date data type: 1987-12-30
I can run a SELECT...
SELECT CONVERT(date, BirthDate) FROM CUSTOMERLIST
But this is only affecting the display. I would like for it to update the entire column and also change the data type of that attribute as well. Any assistance would be greatly appreciated!
You will need to ALTER the table:
ALTER TABLE CUSTOMERLIST ALTER COLUMN BirthDate date not null
See Sql Fiddle with demo