I am using sqlite for local database in mobile and in my database, I have date field with column name RN_CREATE_DATE. My RN_CREATE_DATE column value is in this format 'dd-mm-yy HH:MM:SS' and I want to fetch data with given date. What will be the exact query for that I tried with below database column and value
**RN_CREATE_DATE
2012-07-27 11:04:34
2012-05-28 10:04:34
2012-07-22 09:04:34**
SELECT RN_CREATE_DATE
FROM DISPOSITION
WHERE RN_CREATE_DATE=strftime('%Y', '2012-07-28 12:04:34')
but no result found, just help me out with this.
strftime works like this:
sqlite> select strftime('%d-%m-%Y %H:%M:%S', datetime('now'));
2012-09-13 12:42:56
If you want to use it in a WHERE clause, replace datetime('now') with the datetime you want to match in the YYYY-mm-dd HH:MM:SS format.
Example:
SELECT *
FROM t
WHERE c = strftime('%d-%m-%Y %H:%M:%S', '2012-09-13 12:44:22');
-- dd-mm-YYYY HH:MM:SS YYYY-mm-dd HH:MM:SS
I'd like to add some information about using SQLite Date and Time with UNIX epoch time:
The UNIX epoch was 00:00:00 1970-01-01, i.e. midnight of 1st Jan 1970. The current time on UNIX machines (like those running Linux) is measured in seconds since that time.
SQLite has support for this epoch time, and I've found it very useful for using it as the format for a DateTime field in SQLite.
Concretely, suppose I want to have an Event table, for events like concerts etc. I want a fromDateTime field to store when the event starts. I can do that by setting the fromDateTime filed to type INTEGER, as such:
CREATE TABLE IF NOT EXISTS Event(
eventID INTEGER PRIMARY KEY,
name TEXT,
ratingOutOf10 REAL,
numberOfRatings INTEGER,
category TEXT,
venue TEXT,
fromDateTime INTEGER,
description TEXT,
pricesList TEXT,
termsAndConditions TEXT
);
Now, let's get to the usage of the UNIX epoch with SQLite DateTime fields:
Basic
select strftime('%s', '2016-01-01 00:10:11'); --returns 1451607012
select datetime(1451607012, 'unixepoch'); --returns 2016-01-01 00:10:11
select datetime(1451607012, 'unixepoch', 'localtime'); --returns 2016-01-01 05:40:11 i.e. local time (in India, this is +5:30).
Only dates and/or times:
select strftime('%s', '2016-01-01'); --returns 1451606400
select strftime('%s', '2016-01-01 16:00'); --returns 1451664000
select date(-11168899200, 'unixepoch'); --returns 1616-01-27
select time(-11168899200, 'unixepoch'); --returns 08:00:00
Other stuff:
select strftime('%d-%m-%Y %H:%M:%S', '2012-09-13 12:44:22') --returns 13-09-2012 12:44:22
Now, here's an example usage of the above with our Event table:
EXAMPLE:
insert into Event
(name, ratingOutOf10, numberOfRatings, category, venue, fromDateTime, description, pricesList, termsAndConditions)
VALUES
('Disco', '3.4', '45', 'Adventure; Music;', 'Bombay Hall', strftime('%s','2016-01-27 20:30:50'), 'A dance party', 'Normal: Rs. 50', 'Items lost will not be the concern of the venue host.');
insert into Event
(name, ratingOutOf10, numberOfRatings, category, venue, fromDateTime, description, pricesList, termsAndConditions)
VALUES
('Trekking', '4.1', '100', 'Outdoors;', 'Sanjay Gandhi National Park', strftime('%s','2016-01-27 08:30'), 'A trek through the wilderness', 'Normal: Rs. 0', 'You must be 18 or more and sign a release.');
select * from event where fromDateTime > strftime('%s','2016-01-27 20:30:49');
I like this solution because it's really easy to work with programming languages, without too much thinking of the various formats involved in SQLite's DATE, TIME, DATETIME, etc. data types.
strftime always generates four-digit years, so you have to use substr to cut off the first two digits:
... WHERE RN_CREATE_DATE = strftime('dd-mm-', '2012-07-28 12:04:34') ||
substr(strftime('%Y %H:%M:%S', '2012-07-28 12:04:34'), 3)
It would be easier to store the column values in a format that is directly understood by SQLite.
strftime('%Y', '2012-07-28 12:04:34') returns 2012, as:
sqlite> select strftime('%Y', '2012-07-28 12:04:34');
2012
but the RN_CREATE_DATE is of type datetime, which expect a full datetime like '2012-07-28 12:04:34'. what you want might be simply:
SELECT RN_CREATE_DATE
FROM DISPOSITION
WHERE RN_CREATE_DATE='2012-07-28 12:04:34'
Related
I have an INT64 column called "Date" which contains many different numbers like: "20210209" or "20200305". I want to turn those numbers into a date with this format: MM-YYYY (so in these cases, 02-2021 and 03-2020). Ultimately I want to sum all the data in each month together. The problem is that BigQuery can't convert INT64 to date, only to strings. I'm not sure if I should convert to a string and then to a date or if there is a better way.
Although converting to a string then a date both works and is very concise, over large enough numbers of rows (which may be the case in Big Query) you may be better off using integer maths and using DATE(year, month, day)...
https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
SELECT
DATE(
DIV( 20210209 , 10000), -- Which gives 2021
DIV(MOD(20210209, 10000), 100), -- Which gives 02
MOD(20210209, 100) -- Which gives 09
)
You can convert the value to a string and use parse_date():
select parse_date('%Y%m%d', cast(20210209 as string))
Another option
select date,
regexp_replace('' || date, r'(\d{4})(\d{2})(\d{2})', r'\2-\1') as MM_YYYY
from your_table
if applied to sample data in your question - output is
Yet another option
select date,
format_date('%m-%Y', parse_date('%Y%m%d', '' || date)) as MM_YYYY
from your_table
with same output
Here's the query that returns nothing:
select TOP 10 *
from table
WHERE 'date' BETWEEN '2018-05-01' AND '2018-05-04'
ORDER BY "date";
Nothing is returned.
The following returns 10 rows:
select TOP 10 *
from table
WHERE 'date' = '2018-05-01'
BTW, the date column is TIMESTAMP.
Any thoughts?
Your where clause is always false, because in English it’s:
where the string 'date' is between the string '2018-05-01' and the string '2018-05-04'
which is false.
Change 'date' to "date". You’ll then be comparing the date column (and the date literals will be automatically cast from text to date).
Works fine for me...
CREATE TABLE stackoverflow (foo TIMESTAMP);
INSERT INTO stackoverflow VALUES (GETDATE());
INSERT INTO stackoverflow VALUES ('2016-01-01 00:11:22'::timestamp);
INSERT INTO stackoverflow VALUES ('2018-01-01 01:02:03'::timestamp);
SELECT * FROM stackoverflow
WHERE foo BETWEEN '2017-02-02' AND '2018-05-04';
Data returned:
2018-01-01 01:02:03
Tip: Be careful when mixing dates and timestamps. A comparison like WHERE date = '2018-05-01' might only find timestamps that are exactly at midnight at the start of that day.
I have four columns namely-
1. C_Date in YYYYMMDD format (varchar(255)) Eg. 20161231
2. C_Time in 4-digit Military format (varchar(255)) Eg. 2143
3. E_Date in YYYYMMDD format (varchar(255)) Eg. 20161230
4. E_Time in 4-digit Military format (varchar(255)) Eg. 1600
I want to Calculate the time between E event and C event. How can i perform this computation with a select statement?
Pretty simple to create a date type from the component values:
with data as (select '20161231' as c_date, '2143' as c_time)
select
convert(
datetime,
stuff(stuff(stuff(c_date + ' ' + c_time, 12, 0, ':'), 7, 0, '-'), 5, 0, '-'),
120
) as c_datetime
from data;
Use datediff() to calculate the time difference. You didn't specify how you wanted the output to look so I won't attempt a guess. There should be a hundred other questions out there with information relevant to your question though.
Also note that I did not append ':00' to the string to represent seconds. It seems to work though I couldn't track down an official document to confirm that. So to be safe you may want to tack that on as well. Arguably there could be a more universal format like ISO 8601 that would be a "better" solution. You get the idea though.
A small matter to convert your strings into a datetime. Then we use DateDiff() to calculate the differance between the two dates.
Declare #YourTable table (C_Date varchar(255),C_Time varchar(255),E_Date varchar(255),E_Time varchar(255))
Insert Into #YourTable values
('20161231','2143','20161230','1600')
;with cte as (
Select *
,CDT = try_convert(DateTime,C_Date+' '+stuff(C_Time,3,0,':'))
,EDT = try_convert(DateTime,E_Date+' '+stuff(E_Time,3,0,':'))
from #YourTable
)
Select CDT
,EDT
,Duration = concat(DateDiff(DD,EDT,CDT),' ',Format(DateAdd(Second,DateDiff(SECOND,EDT,CDT),'1899-12-31'),'HH:mm:ss'))
,AsSeconds = DateDiff(SECOND,EDT,CDT)
,AsMinutes = DateDiff(MINUTE,EDT,CDT)
From cte
Returns
CDT EDT Duration AsSeconds AsMinutes
2016-12-31 21:43:00 2016-12-30 16:00:00 1 05:43:00 106980 1783
I am trying to query the minimum datetime from a column that is stored as nvarchar(max). There a a few tricky things with this query (at least for me)
There is more than just the date being stored within each record.
The position of the datetime is relative - although it does always appear in the format **(DD-MM-YY at HH:MM PM
There are multiple datetimes stored in each record - so not only do I need to locate and capture where there is a datetime, I need to find the minimum datetime within the record
I can't just change the format that the data is stored in - there is over a decade of information that is stored this way.
The column is called 'hdresp' - here is sample data:
**(03-Apr-14 at 09:44 AM email sent) -- Billy Bob: Upgrade ordered. **(02-Apr-14 at 04:16 PM email sent) -- Sammy Richards: I can give you another cable to if you think that will help but it just might be time for an upgrade. If you want to go that route I have to ask that you submit another request for New Hardware. **(02-Apr-14 at 03:17 PM email sent) -- Paul Smith: Michael Stop by my desk when you have a second.
What I would like to end up with is a query that identifies 02-Apr-14 at 3:17 PM as the minimum time and converts it to YYYY-MM-DD HH:MM:SS - for example 2014-04-02 15:17:00
Perhaps you could try this approach:
select hdresp, min(ts) as timestamp
from (
select hdresp, cast(substring(hdresp,delta+3,10)+substring(hdresp,delta+15,9) as datetime2) as ts
from (
select
hdresp,
charindex('**(',hdresp,1) as delta
from problem
union
select
hdresp,
charindex('**(',hdresp,1+charindex('**(',hdresp,1)) as delta
from problem
union
select
hdresp,
charindex('**(',hdresp,1+charindex('**(',hdresp,1+charindex('**(',hdresp,1))) as delta
from problem
union
select
hdresp,
charindex('**(',hdresp,1+charindex('**(',hdresp,1+charindex('**(',hdresp,1+charindex('**(',hdresp,1)))) as delta
from problem
) as temp1
where delta > 0
) as temp2
group by hdresp
;
See example here: http://sqlfiddle.com/#!3/a1a99/1
If there are more than 4 possible timestamps in a hdresp, just add more UNION SELECT... sections.
Thank you everyone for your help!
I ended up using this to extract and convert the minimum time from a string:
SELECT CONVERT(datetime, REPLACE(LEFT(RIGHT(hdresp, PATINDEX('%(**%', REVERSE(hdresp)) - 1), 21), 'at ', ''))
from tblhdmain
where hdindex = 211458
Which gave me the result:
2014-04-02 15:17:00.000
I got a column called DateOfBirth in my csv file with Excel Date Serial Number Date
Example:
36464
37104
35412
When i formatted cells in excel these are converted as
36464 => 1/11/1999
37104 => 1/08/2001
35412 => 13/12/1996
I need to do this transformation in SSIS or in SQL. How can this be achieved?
In SQL:
select dateadd(d,36464,'1899-12-30')
-- or thanks to rcdmk
select CAST(36464 - 2 as SmallDateTime)
In SSIS, see here
http://msdn.microsoft.com/en-us/library/ms141719.aspx
The marked answer is not working fine, please change the date to "1899-12-30" instead of "1899-12-31".
select dateadd(d,36464,'1899-12-30')
You can cast it to a SQL SMALLDATETIME:
CAST(36464 - 2 as SMALLDATETIME)
MS SQL Server counts its dates from 01/01/1900 and Excel from 12/30/1899 = 2 days less.
tldr:
select cast(#Input - 2e as datetime)
Explanation:
Excel stores datetimes as a floating point number that represents elapsed time since the beginning of the 20th century, and SQL Server can readily cast between floats and datetimes in the same manner. The difference between Excel and SQL server's conversion of this number to datetimes is 2 days (as of 1900-03-01, that is). Using a literal of 2e for this difference informs SQL Server to implicitly convert other datatypes to floats for very input-friendly and simple queries:
select
cast('43861.875433912' - 2e as datetime) as ExcelToSql, -- even varchar works!
cast(cast('2020-01-31 21:00:37.490' as datetime) + 2e as float) as SqlToExcel
-- Results:
-- ExcelToSql SqlToExcel
-- 2020-01-31 21:00:37.490 43861.875433912
this actually worked for me
dateadd(mi,CONVERT(numeric(17,5),41869.166666666664)*1440,'1899-12-30')
(minus 1 more day in the date)
referring to the negative commented post
SSIS Solution
The DT_DATE data type is implemented using an 8-byte floating-point number. Days are represented by whole number increments, starting with 30 December 1899, and midnight as time zero. Hour values are expressed as the absolute value of the fractional part of the number. However, a floating point value cannot represent all real values; therefore, there are limits on the range of dates that can be presented in DT_DATE. Read more
From the description above you can see that you can convert these values implicitly when mapping them to a DT_DATE Column after converting it to a 8-byte floating-point number DT_R8.
Use a derived column transformation to convert this column to 8-byte floating-point number:
(DT_R8)[dateColumn]
Then map it to a DT_DATE column
Or cast it twice:
(DT_DATE)(DT_R8)[dateColumn]
You can check my full answer here:
Is there a better way to parse [Integer].[Integer] style dates in SSIS?
Found this topic helpful so much so created a quick SQL UDF for it.
CREATE FUNCTION dbo.ConvertExcelSerialDateToSQL
(
#serial INT
)
RETURNS DATETIME
AS
BEGIN
DECLARE #dt AS DATETIME
SELECT #dt =
CASE
WHEN #serial is not null THEN CAST(#serial - 2 AS DATETIME)
ELSE NULL
END
RETURN #dt
END
GO
I had to take this to the next level because my Excel dates also had times, so I had values like this:
42039.46406 --> 02/04/2015 11:08 AM
42002.37709 --> 12/29/2014 09:03 AM
42032.61869 --> 01/28/2015 02:50 PM
(also, to complicate it a little more, my numeric value with decimal was saved as an NVARCHAR)
The SQL I used to make this conversion is:
SELECT DATEADD(SECOND, (
CONVERT(FLOAT, t.ColumnName) -
FLOOR(CONVERT(FLOAT, t.ColumnName))
) * 86400,
DATEADD(DAY, CONVERT(FLOAT, t.ColumnName), '1899-12-30')
)
In postgresql, you can use the following syntax:
SELECT ((DATE('1899-12-30') + INTERVAL '1 day' * FLOOR(38242.7711805556)) + (INTERVAL '1 sec' * (38242.7711805556 - FLOOR(38242.7711805556)) * 3600 * 24)) as date
In this case, 38242.7711805556 represents 2004-09-12 18:30:30 in excel format
In addition of #Nick.McDermaid answer I would like to post this solution, which convert not only the day but also the hours, minutes and seconds:
SELECT DATEADD(s, (42948.123 - FLOOR(42948.123))*3600*24, dateadd(d, FLOOR(42948.123),'1899-12-30'))
For example
42948.123 to 2017-08-01 02:57:07.000
42818.7166666667 to 2017-03-24 17:12:00.000
You can do this if you just need to display the date in a view:
CAST will be faster than CONVERT if you have a large amount of data, also remember to subtract (2) from the excel date:
CAST(CAST(CAST([Column_With_Date]-2 AS INT)AS smalldatetime) AS DATE)
If you need to update the column to show a date you can either update through a join (self join if necessary) or simply try the following:
You may not need to cast the excel date as INT but since the table I was working with was a varchar I had to do that manipulation first. I also did not want the "time" element so I needed to remove that element with the final cast as "date."
UPDATE [Table_with_Date]
SET [Column_With_Excel_Date] = CAST(CAST(CAST([Column_With_Excel_Date]-2 AS INT)AS smalldatetime) AS DATE)
If you are unsure of what you would like to do with this test and re-test! Make a copy of your table if you need. You can always create a view!
Google BigQuery solution
Standard SQL
Select Date, DATETIME_ADD(DATETIME(xy, xm, xd, 0, 0, 0), INTERVAL xonlyseconds SECOND) xaxsa
from (
Select Date, EXTRACT(YEAR FROM xonlydate) xy, EXTRACT(MONTH FROM xonlydate) xm, EXTRACT(DAY FROM xonlydate) xd, xonlyseconds
From (
Select Date
, DATE_ADD(DATE '1899-12-30', INTERVAL cast(FLOOR(cast(Date as FLOAT64)) as INT64) DAY ) xonlydate
, cast(FLOOR( ( cast(Date as FLOAT64) - cast(FLOOR( cast(Date as FLOAT64)) as INT64) ) * 86400 ) as INT64) xonlyseconds
FROM (Select '43168.682974537034' Date) -- 09.03.2018 16:23:28
) xx1
)
For those looking how to do this in excel (outside of formatting to a date field) you can do this by using the Text function https://exceljet.net/excel-functions/excel-text-function
i.e.
A1 = 132134
=Text(A1,"MM-DD-YYYY") will result in a date
This worked for me because sometimes the field was a numeric to get the time portion.
Command:
dateadd(mi,CONVERT(numeric(17,5),41869.166666666664)*1440,'1899-12-31')