I have a Table, where there is a datetime Column, I want to match this column by passing only date & datetime column is heaving date & time both (i.e 25/06/2013 4:54:12 PM).
It's usually best in this situation to leave the column alone and do some manipulation on your parameter. So if you're passing a #SearchDate parameter, I'd do:
SELECT abc from mytable
where
datetimecolumn >= #SearchDate and
datetimecolumn < DATEADD(day,1,#SearchDate)
I believe that, if you're running on SQL Server 2008 or later, and use the following:
SELECT abc from mytable
where
CAST(datetimecolumn as date) = #SearchDate
That an index on datetimecolumn can be used. Whereas I'm certain that an index is usable given my first query. You should, in general, be wary of calling functions on columns - such actions can often cripple performance by forcing a full table scan.
And unlike you're accepted answer, I would always seek to avoid treating dates as strings - as soon as you do, you're inviting all kinds of issues around formatting.
datetime format in t-sql is a little tricky, first of all you need to be aware of date time (i.e 25/06/2013 4:54:12 PM) is greater than 25/06/2013 , so you need to use > and < operators, for ![enter image description here][1]example orderdate > '20130625' AND orderdate < '20130626' , sql server considers 'YYYYMMDD' as global datetime format and it is language independent. take a look at the attachement...
try -:
DECLARE #givenDate DATE;
DECLARE #t AS TABLE (
fld_DateTime DATETIME
)
SET #givenDate = '2013-04-24'
INSERT INTO #t ( fld_DateTime )
VALUES ('2013-04-23 14:37:59.580')
, ('2013-04-23 14:59:02.403')
, ('2013-04-23 15:15:36.890')
, ('2013-04-24 08:57:45.800')
, ('2013-04-24 10:44:56.663')
, ('2013-04-24 13:18:20.760')
, ('2013-04-25 09:38:55.503')
, ('2013-06-28 09:20:11.007')
, ('2013-06-28 12:37:04.973')
, ('2013-06-28 12:38:50.130')
, ('2013-07-03 15:27:36.167')
SELECT fld_DateTime
FROM #t
WHERE fld_DateTime >= #givenDate AND fld_DateTime < DATEADD(DAY, 1, #givenDate)
You can use CAST and CONVERT functions for converting date
http://msdn.microsoft.com/en-us/library/ms187928(v=sql.105).aspx
For example
select *
from datetimetable
where convert(char(10), datetimecolumn, 103) = '25/12/2013'
BUT remember, that this code is for testing purposes only.
I recommend you to play with different parameters of CONVERT function
in order to better understand it (and to play with different sizes of the first parameter)
please, view solutions in the other answers on your question to find out the best one for your environment
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
Using SQL Server 2014, I have a date field named LAST_BASELINE_UPDATE_DATE that is stored as datetime.
I used the CONVERT function to convert to mm/dd/yyyy:
convert(date,LAST_BASELINE_UPDATE_DATE,101) as BASELINE_UPDATE_DATE
What I want to be able to do is then select the MAX value of BASELINE_UPDATE_DATE without creating a table. Is this even possible?
It's a little unclear from your post what your data is and what you're trying to get out. Here are a couple solutions, hopefully one of which is applicable
Assuming you want your result as a string formatted mm/dd/yyyy you can do this
select convert(varchar(10), max(LAST_BASELINE_UPDATE_DATE), 101))
from YourTable
If you just need it as a date, just do
select max(LAST_BASELINE_UPDATE_DATE)
from YourTable
if LAST_BASELINE_UPDATE_DATE is already a string (formatted mm/dd/yyyy) and you want it as a date,
select max(convert(date, LAST_BASELINE_UPDATE_DATE, 101))
from YourTable
I think you are complicating this. Just do the conversion on the max datetime values.
declare #table table (LAST_BASELINE_UPDATE_DATE datetime)
insert into #table
values
('20160701 12:21'),
('20160705 03:21'),
('20160401 19:21'),
('20161201 04:21')
select
convert(varchar(10),max(LAST_BASELINE_UPDATE_DATE),101)
from
#table
This method converts your single returned row, which is the max() value of your datetime columns, as opposed to converting every row and then finding the max value.
I have a SQL Server table Companies which contains a column UserDefined4 of type nvarchar(100).
This column contains some text plus a date in the format DD.MM.YYYY
I want to select the records in the month of March and April 2014.
I am running this query,
SELECT
(Right(Companies.UserDefined4, 10))
FROM
Companies
WHERE
(Right(Companies.UserDefined4, 10) not like '%[^0-9.]%'
AND (Right(Companies.UserDefined4, 10) not like ''))
AND (CONVERT(Date,Right(Companies.UserDefined4, 10),104) >= '2014-03-01'
and
CONVERT(Date,Right(Companies.UserDefined4, 10),104) <= '2014-04-30')
This query throws an error
Error converting a string to a date and / or time.
I have checked one by one all the records and they contains date in proper format. The strange thing for me is that the same query runs if I put OR instead of AND in following part, in the same query:
(
CONVERT(Date,Right(Companies.UserDefined4, 10),104) >= '2014-03-01'
OR
CONVERT(Date,Right(Companies.UserDefined4, 10),104) <= '2014-04-30'
)
I know, its not a wise decision to save date as a NVarChar but I have to work with this data. I am not the one who designed this database.
I've had similar problems in the past and they were all due to some of the columns not ending with the expected characters (dates in your case) and the "guard clauses" (in your case the 1st two conditions in the WHERE) not stopping the query engine from applying the "range conditions" (in your case, the last two conditions in the WHERE).
Note that I don't know exactly why that happens (maybe query optimization, no "short-circuit" evaluation or the order in that the evaluation occurs isn't what we expect -- this is me speculating), but I've noticed that if you store an intermediate result of the query (with only the "guard clauses" applied) in a temporary structure (a table variable for example) and then apply the "range clauses" to that interim result, it'll work.
For example, this will work even if there are "bad" rows (rows that don't end in a date):
DECLARE #t TABLE (userdate CHAR(10))
INSERT #t
SELECT RIGHT(Companies.UserDefined4, 10)
FROM Companies
WHERE RIGHT(Companies.UserDefined4, 10) NOT LIKE '%[^0-9.]%'
AND RIGHT(Companies.UserDefined4, 10) <> ''
SELECT *
FROM #t
WHERE CONVERT(DATE, userdate, 104) >= '2014-03-01'
AND CONVERT(DATE, userdate, 104) <= '2014-04-30'
You can check a fiddle demonstrating the issue here.
Can you be sure that UserDefined4 really always contains a date in that format in the right-most 10 characters?
If so, you could create a computed column like this:
ALTER TABLE dbo.Companies
ADD DateFromUD4 AS CONVERT(DATE, RIGHT(UserDefined4, 10), 104) PERSISTED
and then the query becomes really simple:
SELECT
(list of columns)
FROM
dbo.Companies
WHERE
DateFromUD4 >= '20140301' AND
DateFromUD4 <= '20140430'
I like to use the ISO-8601 format (YYYYMMDD without any dashes) for specifying dates as string since this is guaranteed to work on any SQL Server regardless of the date and language settings.
Since the conversion goes to a DATE, you won't have to worry about time portions either - this is a date-only computed column. This works in SQL Server 2008 and newer.
I have a scenario where I have an int column with the following dates for example:
20131210
20131209
What I want is, I want to convert the above to a date datatype so that I can use it with GETDATE() function.
This is my try but I am getting an error:
SELECT CONVERT(DATETIME, CONVERT(varchar(8), MyColumnName))
FROM MyTable
WHERE DATEADD(day, -2, CONVERT(DATETIME, CONVERT(CHAR(8), MyColumnName))) < GetDate()
This is the error I am getting:
Conversion failed when converting date and/or time from character string.
You have at least one bad date in your column (it could be 99999999 or 20130231 or who knows). This is what happens when you choose the wrong data type. You can identify the bad row(s) using:
SELECT MyColumnName FROM dbo.MyTable
WHERE ISDATE(CONVERT(CHAR(8), MyColumnMame)) = 0;
Then you can fix them or delete them.
Once you do that, you should fix the table. There is absolutely no upside to storing dates as integers, and a whole lot of downsides.
Once you have the date being stored in the correct format, your query is much simpler. And I highly recommend applying functions etc. to the right-hand side of the predicate as opposed to applying it to the column (this kills SQL Server's ability to make efficient use of any index on that column, which you should have if this is a common query pattern).
SELECT MyColumnName
FROM dbo.MyTable
WHERE MyColumnName < DATEADD(DAY, 2, GETDATE());
Try:
CREATE TABLE IntsToDates(
Ints INT
)
INSERT INTO IntsToDates
VALUES (20131210)
, (20131209)
SELECT CAST(CAST(Ints AS VARCHAR(12)) AS DATE)
FROM IntsToDates
I've had a similar problem where I need to convert INT to DATE and needed to cater for values of 0. This case statement did the trick for me
CASE MySourceColumn
WHEN ISDATE(CONVERT(CHAR(8),MySourceColumn)) THEN CAST('19000101' AS DATE)
ELSE CAST(CAST(MySourceColumn AS CHAR) AS DATE)
END
AS MyTargetColumn
I'm in SQL Server 2008 and I have been working on making some older code use parameters instead of building the queries using string concatenation. And I'm also working on making things work faster by doing things like adding indexes to tables.
The table I am working with has many columns (it's the heart of a star schema reporting database) and has more than 4M rows. The create for the table looks like:
CREATE TABLE [dbo].[rptTransaction](
...
[Date] [nvarchar](10) NULL,
...
) ON [PRIMARY]
Yes, the date column is poorly named because it collides with a keyword. They are using string dates [remember it's a reporting database].
When I execute the following code in MS SQL Server Management Studio:
DECLARE #testDate NVARCHAR = N'2012/03/01';
SELECT COUNT(*)
FROM rptTransaction AS t
WHERE t.Date >= #testDate
AND t.Date <= #testDate
OPTION (RECOMPILE);
GO
The results are as follows:
(No column name)
0
On the other hand when I execute the following code:
DECLARE #testDate NVARCHAR = N'2012/03/01';
SELECT COUNT(*)
FROM rptTransaction AS t
WHERE t.Date >= N'2012/03/01'
AND t.Date <= N'2012/03/01'
OPTION (RECOMPILE);
GO
The result is the following:
(No column name)
124888
(I am using the OPTION (RECOMPILE) because otherwise the parametrized version does a full table scan, which takes a long time.)
Run this code:
declare #testDate nvarchar = N'2012/03/01';
select #testDate ;
One my system, the output was just 2.
Try this instead:
declare #testDate nvarchar(10) = N'2012/03/01';
select #testDate ;
Much better:
2012/03/01
That's one of two unexpected parts of your query. The other is that you required your value be both >= and <=. In other words, the only way to satisfy the query is if the parameter matched your stored data exactly. 2 is never going to do that if the column is all valid dates.
nvarchar by default uses a length 1.specify the length say 10 in this case