I have a table having column order date like this 2019-06-01.
But I need to show date and time also like this 2019-06-01 00:00:00.000
Please suggest
You should be able to do a simple CAST() assuming your type is a date like you mentioned. It is stored as a date, but you want it to be presented as a datetime.
SELECT CAST(your_col AS DATETIME) AS your_col
FROM your_table
There are a few ways to do it. This should be pretty straight forward though:
DECLARE #TEST DATE
SET #TEST = '2019-06-01'
SELECT CONVERT(DATETIME, #TEST)
yields:
2019-06-01 00:00:00.000
Really doing what you are looking for, making your datatype of DATE into DATETIME
However as suggested in the comments depending on how this data is used you might just want to append stuff to it on the presentation layer. Really up to you! Good luck. :)
Related
I have test table where column sys_created_on(datatype is varchar(15)) is a datetime field and we receive two different date formats like below.
03-04-2022 12:49
2/28/2022 10:35
Expected Result is:
03-04-2022 12:49
02-28-2022 10:35
Could you please suggest if there is any way to convert all formats to one format instead..
any suggestions can be appreciated. Please suggest if datatype change can help anything here.
Thank you!!
The best thing to do here would be to just convert your text timestamp column to a bona fide timestamp column. You could achieve this using the TO_TIMESTAMP() function along with a CASE expression:
SELECT
ts,
CASE WHEN REGEXP_LIKE(ts, '\\d{1,2}-\\d{2}-\\d{4} \\d{1,2}:\\d{2}')
THEN TO_TIMESTAMP(ts, 'mm-dd-yyyy hh24:mi')
ELSE TO_TIMESTAMP(ts, 'mm/dd/yyyy hh24:mi') END AS ts_real
FROM yourTable;
Assuming you had a new timestamp column, you could populate it using the ts text column as follows:
UPDATE yourTable
SET ts_real = CASE WHEN REGEXP_LIKE(ts, '\\d{1,2}-\\d{2}-\\d{4} \\d{1,2}:\\d{2}')
THEN TO_TIMESTAMP(ts, 'mm-dd-yyyy hh24:mi')
ELSE TO_TIMESTAMP(ts, 'mm/dd/yyyy hh24:mi') END;
TRY_TO_DATE return null if it fails so you can just chain different formats together with COALESCE or NVL
SELECT column1,
TRY_TO_DATE(column1, 'dd-mm-yyyy hh:mi') as d1,
TRY_TO_DATE(column1, 'mm/dd/yyyy hh:mi') as d2
,nvl(d1,d2) as answer
FROM VALUES ('03-04-2022 12:49'),('2/28/2022 10:35');
gives:
COLUMN1
D1
D2
ANSWER
03-04-2022 12:49
2022-04-03
2022-04-03
2/28/2022 10:35
2022-02-28
2022-02-28
which can be merged as
,nvl(TRY_TO_DATE(column1, 'dd-mm-yyyy hh:mi'),TRY_TO_DATE(column1, 'mm/dd/yyyy hh:mi')) as answer
ah, didn't read well enough, to make them all the same, UPDATE but use the "local format" thus just a TO_CHAR
thus:
UPDATE table
SET sys_created_on = to_char(nvl(
TRY_TO_TIMESTAMP(sys_created_on , 'dd-mm-yyyy hh:mi'),
TRY_TO_TIMESTAMP(sys_created_on , 'mm/dd/yyyy hh:mi')
));
Replace the separator using replace():
update test_table
set sys_created_on = replace(sys_created_on,'/','-');
If you're also dealing with different day and month field order, look into regexp_replace() to swap their places:
update test_table
set sys_created_on = regexp_replace(sys_created_on,
'(.*)/(.*)/(.*)',
'\\2-\\1-\\3');
That's in case your 03-04-2022 is in format dd-mm-yyyy making it April 3rd, not March 4th. It's good to know what exact format you're dealing with. In extreme cases you might even need to make sure whether your hour field is 24-h or 12-h-based but missing an am/pm meridiem indicator.
As suggested by Tim's and Simeon's answers, a matching data type is always encouraged. It takes less space, queries faster, enables type-specific functions and maintains validity of data (varchar doesn't care if you get February 30th or 32nd day of month 13, at 25:60)
If you want to keep the cookie and eat it too, here's how you can add one virtual column where you'll always see a standardised version of your sys_created_on, and another one, which will always interpret it as a proper timestamp. This way you don't need to touch anything in how the table is populated, keep the original, unprocessed data, see how it gets standardised, and also benefit from a timestamp data type, while not using up any additional space:
alter table test_table
add column standardised_sys_created_on varchar(15)
as replace(sys_created_on,'/','-'),
add column timestamp_sys_created_on TIMESTAMP_NTZ
as coalesce(
try_to_date(sys_created_on, 'dd-mm-yyyy hh24:mi'),
try_to_date(sys_created_on, 'dd/mm/yyyy hh24:mi'));
To make it faster at the expense of materializing them, you can turn those virtual columns into generated/computed using default.
I am using the latest SQL Server. I have a table with a CreatedDate column. I need to write a Query that uses dates that are plus or minus 7 from the Date in CreatedDate. I have no clue how to go about this. My thought was this:
DECLARE #Date datetime
DECLARE #SevenBefore datetime
DECLARE #SevenAfter datetime
SET #Date = CreatedDate
SET #SevenBefore = DATEADD(day,-7,#Date)
SET #SevenAfter = DATEADD(day,7,#Date)
SELECT *
FROM <table>
WHERE <table> BETWEEN #SevenBefore AND #SevenAfter
The issue with this is that I cannot use "CreatedDate" as a SET #DATE because SQL gives an error "Invalid column name 'CreatedDate'"
Any help would be appreciated. I cannot list a date because every date in that column could be different.
Thanks
In this case, you need to stop thinking as a programmer would, and start thinking as a Database programmer would.
Lets work only with this central part of your query:
SELECT *
FROM <table>
WHERE <table> BETWEEN #SevenBefore AND #SevenAfter
Now, you say that the CreatedDate is a column in a table. For this example, I will assume that the CreatedDate is in a table other than the one in your example above. For this purpose, I will give two fake names to the tables. The table with the CreatedDate, I will call tblCreated, and the one from the query above I will call tblData.
Looking above, it's pretty obvious that you can't compare an entire table row to a date. There must be a field in that table that contains a date/time value. I will call this column TargetDate.
Given these assumptions, your query would look something like:
SELECT *
FROM tblCreated tc
INNER JOIN tblData td
ON td.TargetDate BETWEEN DATEADD(day, -7, tc.CreatedDate) and DATEADD(day, 7, tc.CreatedDate)
Looking at this, it is clear that you still need some other associations between the tables. Do you only want all data rows per customer based on the Created date, or perhaps only want Creations where some work was done on them as shown in the Data records, or ??. Without a fuller specification, we can't help with that, though.
I have column Terms in my table and it contains data like this:
30D, 40D, etc.
D represents days.
My question: how can I sum date in Terms column? How can I convert string to int?
Thank you in advance.
Just use REPLACE to ditch the D and CONVERT to convert the varchar to a number....
SELECT SUM(CONVERT(int, REPLACE(Terms,'D',''))) FROM TableName
Edit: Commentor is right, CAST would work too.
And I dont get all the down votes. The guy's just asking a SQL question.
Jeez... Tough crowd.
Edit2:
OK, based on comments, it seems like you would like to get a "due date" from the terms (say, TODAY + 30D or "today + 30 days"). To do that, we'd need a DATE column. OR, we can just use today's date (GETDATE())
Assume your table has a date column called ... dt
The SQL to pull dt+'30D' would require us to add 30 "days" to dt.
DATEADD will add days, and the aforementioned CONVERT+REPLACE combo will convert '30D' to just plain '30' ...
So, you end up with the following SQL:
SELECT DATEADD(day, CONVERT(int, REPLACE(Terms,'D','')), dt) FROM TableName
The 'day' tells DATEADD to add days (that seems really obvious ... now),
the CONVERT+REPLACE tells it how many days to add
AND - dt is our column name.
SO - how about just adding "30D" to TODAY? Easy. We just swap out dt with GETDATE() ...
SELECT DATEADD(day, CONVERT(int, REPLACE(Terms,'D','')), GETDATE()) FROM TableName
SELECT AVG(SALARY) - AVG(CONVERT(int, REPLACE(SALARY,'0','')))
FROM EMPLOYEES;
I have a little problem with my SQL Query:
I have this value on my table: 2014-10-23 00:00:00
I have a record like this each 2 minutes every day, and I need to SELECT all the value of today.
Now I made this:
WHERE mytable.data LIKE CURDATE()
and it doesn't work. I tried a lot of things found here on stackoverflow and nothing could help me.
Thanks for answer.
You don't say which version of SQL Server you are using, if you have the DATE data type available you can cast the datetime returned by getdate() or CURRENT_TIMESTAMP to strip off the time part.
But then you need a range to find all the matching rows, something like:
SELECT *
FROM mytable
WHERE mytable.data >= CAST(GETDATE() AS date)
AND mytable.data < CAST(DATEADD(day, 1, GETDATE()) AS date)
SQL Fiddle
The scenario is this:
select max date from some table, when the target table having no data, so the max date is null. when the date being null, I want to get the earliest date of system, so the epoch time seems perfect.
I have searched some ways including DATEADD functions, but that seems not elegant.
If I understand your question correctly, in SQL Server the epoch is given by cast(0 as datetime) :
select Max(ISNULL(MyDateCol, cast(0 as datetime)))
from someTable
group by SomeCol
The earliest date that can be stored in a SQL datetime field depends on the data type you use:
datetime:
1753-01-01 through 9999-12-31
smalldatetime:
1900-01-01 through 2079-06-06
date, datetime2 and datetimeoffset:
0001-01-01 through 9999-12-31
For more exact details see from https://msdn.microsoft.com/en-GB/library/ms186724.aspx#DateandTimeDataTypes
The epoch is useful if you are converting numbers to dates, but irrelevant if you are storing dates as dates.
If you don't want to deal with nulls properly the simple answer is to pick a date that you know will be before your data and hard-code it into your query. cast('1900-01-01' as datetime) will work in most cases.
While using something like cast(0 as datetime) produces the same result it obscures what you have done in your code. Someone maintaining it, wondering where these odd old dates come from, will be able to spot the hard coded date more quickly.
If you define the epoch as Jan 1, 1970: The better: to store it in a variable
DECLARE #epoch DATETIME
SET #epoch = CONVERT( DATETIME, '01 JAN 1970', 106 )
select
DATEPART(YEAR, DATEADD(day, 180, #epoch)) as year,
...