I have a SQL query that is pulling data into excel. My VBA code reads in numbers from user inputs and writes the SQL code with these parameters in it. I can make the comparisons that I need like part number doing it this way, but I cannot get date comparisons to work. In the database I am pulling from is a date column and I have user inputs of day, month, and year.
Basically I need this to work:
WEEKENDING_DT >= DATE(2017,01,01)
But there is no date function in SQL. From my research I also found these ways to do it and none of them work.
WEEKENDING_DT >= (CAST(2017 AS VARCHAR(4)) + RIGHT('0' + CAST(1 AS VARCHAR(2)), 2) + RIGHT('0' + CAST(1 AS VARCHAR(2)), 2))
WEEKENDING_DT >= CAST(CAST(2017 AS VARCHAR(4)) + RIGHT('0' + CAST(1 AS VARCHAR(2)), 2) + RIGHT('0' + CAST(1 AS VARCHAR(2)), 2) AS DATETIME)
Related
I am facing a problem in conversion and type cast. I've a field which is of Data Type BigInt that has a value stored in the format "yyyymmddhhmmss" like "20170609043000". I am trying to get the substring of date part in the timestamp like 20170609 with a separator as 2017-06-09. Not able to fetch the date part in the timestamp.
Query I tried to fetch the Date part:
SELECT CONVERT(date,SUBSTRING(CAST(STR(evt.StartDate,15) as varchar),1, 5), 102) from Event evt
SELECT DATEADD(hour,-5, CONVERT(datetime, SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar),6, 2) + '-' + SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 8, 2) + '-' + SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 1,5) + ' ' + SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar),10, 2) + ':' +SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 12, 2) + ':' + SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 14, 2), 120)) from Event evt
The first query returns the converted date but the month and date remains same , concatenation doesn't work if I try to substring month and date.
Second query doesn't work at all.
Any help would be great.
Why not just take the 8 left most characters, and convert it?
SELECT CONVERT(date, LEFT(20170609043000,8));
Ideally though, you should be using a date and time datatype to store your date and time data. Storing them in a different data type only ends up causing problems and never solves a problem that can't be solved else where (aka your presentation layer).
Your second query is almost right but is getting the year, month, date in the wrong order. Try this instead:
SELECT CONVERT(datetime, SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar),2, 4) + '-' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 6, 2) + '-' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 8,2) + ' ' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar),10, 2) + ':' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 12, 2) + ':' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 14, 2), 120)
FROM Event evt
Output:
09/06/2017 04:30:00
Demo on dbfiddle
I am currently migrating all of my company's reports into Splunk Data Labs input for ingestion. The reports create temp tables using the CREATE TABLE format, which is incompatible with Splunk, however, SELECT INTO format works just fine.
The error that I am getting however when changing to the SELECT INTO format, is the DATETIME variable which should be MM/DD/YYYY hh:mm format loses the hh:mm end, and instead shows MM/DD/YYYY MM/DD/YYYY:
Original SQL:
CREATE TABLE #Stats#(date_slice DATETIME NULL, raw_value REAL NULL)
INSERT INTO #Stats#
SELECT CONVERT(CHAR(11), data_datetime, 111) + ' ' +
CASE WHEN DATEPART(MINUTE, data_datetime) < 30 THEN
RIGHT('0' + LTRIM(str(DATEPART(hour, data_datetime))), 2) + ':00' ELSE
RIGHT('0' + LTRIM(str(DATEPART(hour, data_datetime))), 2) + ':30' END AS date_hour
,SUM(ship_qty) AS moves
FROM #tmpAllData
GROUP BY CONVERT(CHAR(11), data_datetime, 111) + ' ' +
case when DATEPART(minute, data_datetime) < 30 THEN
RIGHT('0' + LTRIM(str(DATEPART(hour, data_datetime))), 2) + ':00' ELSE
RIGHT('0' + LTRIM(str(DATEPART(hour, data_datetime))), 2) + ':30' END
ORDER BY 1
Modified SQL:
--CREATE TABLE #Stats#(date_slice DATETIME NULL, raw_value REAL NULL)
SELECT CONVERT(CHAR(11), data_datetime, 111) + ' ' +
CASE WHEN DATEPART(MINUTE, data_datetime) < 30 THEN
RIGHT('0' + LTRIM(str(DATEPART(hour, data_datetime))), 2) + ':00' ELSE
RIGHT('0' + LTRIM(str(DATEPART(hour, data_datetime))), 2) + ':30' END date_slice
,SUM(ship_qty) raw_value
INTO #Stats#
FROM #tmpAllData
GROUP BY CONVERT(CHAR(11), data_datetime, 111) + ' ' +
case when DATEPART(minute, data_datetime) < 30 THEN
RIGHT('0' + LTRIM(str(DATEPART(hour, data_datetime))), 2) + ':00' ELSE
RIGHT('0' + LTRIM(str(DATEPART(hour, data_datetime))), 2) + ':30' END
ORDER BY 1
Original Output: "07/12/2018 10:00:00 "
Modified Output: "2018/07/12 2018/07/12"
You second statement is creating the temporary table #Stats without any preset column definitions. It instead creates the columns based on the return data type of the SELECT
This means that the SQL Server is not reading the output in question as a DATETIME but instead as a STR.
I would try to use a CONVERT in your modified statement to see if you get different functionality.
It sounds like this question is mostly for your curiosity so I will add that the original statement is the standard way to accomplish what you've outlined.
This is because SELECT... INTO statements are harder to read and revise for new users and because they can lead to some unexpected functionality as you have displayed above.
So, similar to what Edward had said. The query I had posted was returning a DATETIME data type, however, at the very end of the query when it selects all information to display to the user, it got converted to CHAR somewhere in between, so I just converted it to DATETIME before converting to CHAR and splitting up the values.
Running the queries below i get the output '16:6' and '3:40'.
It shows the zero on the second one, but for the first it shows '16:6'
The first one makes it look like '16:60' which by time would be wrong.
How can I make it show '16:06' and not mess up anything else?
SELECT
right('0' + convert(float,datediff (second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245')/ 60 ), 2) + ':' +
right('0' + convert(float,datediff (second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245')% 60),2) as total_time
SELECT
right('0' + convert(float,datediff (second, '2015-02-09 08:07:35.284','2015-02-09 08:11:15.863')/ 60 ), 2) + ':' +
right('0' + convert(float,datediff (second, '2015-02-09 08:07:35.284','2015-02-09 08:11:15.863')% 60),2) as total_time
Use VARCHAR() instead of FLOAT:
SELECT
right('0' + convert(VARCHAR(4),datediff (second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245')/ 60 ), 2) + ':'
+right('0' + convert(VARCHAR(4),datediff (second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245')% 60),2) as total_time
The point of the RIGHT('0'+ ... ),2) portion is to add a leading zero to 1-digit values, but it only works on strings.
If you want to show more than 2 digits for the minutes portion you'll have to change how you go about adding leading zeroes.
Assuming this is T-SQL, with one datediff:
SELECT
right(convert(varchar, dateadd(second, datediff(second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245'), 0), 108), 5) as total_time
I've always found SQL Server date formatting to be counter intuitive. I am pretty sure I already know the only answer is to use a slew of convert and string functions but thought I would ask just in case.
How do you get SQL Server to format a datetime to look like:
%Y-%m-%d %I:%M%P or '2012-04-05 11:56am'
My current approach involves pulling back data with SELECT CONVERT(VARCHAR(19), GETDATE(), 120) and then looping server/client side in code. This I find inefficient in some scenarios when exporting data say to CSV.
DECLARE #d AS datetime;
SET #d = '2012-04-04 16:43:00'
SELECT LEFT(CONVERT(VARCHAR, #d, 120), 11)
+ RIGHT('0' + LTRIM(SUBSTRING(CONVERT(VARCHAR, #d, 131), 12, 5)), 5)
+ LOWER(RIGHT(CONVERT(VARCHAR, #d, 131), 2))
--2012-04-04 04:43pm
select
cast(datepart(YYYY, GETDATE()) as varchar) + '-' +
right('0' + cast(datepart(MM, GETDATE()) as varchar), 2) + '-' +
right('0' + cast(datepart(DD, GETDATE()) as varchar), 2) + ' ' +
LTRIM(RIGHT(cast(GETDATE() AS varchar), 8))
I think the real answer is "You don't", unless you upgrade your SQL Server instances to SQL Server 2012.
FORMAT (Transact-SQL)
What is the DATE FORMAT CODE for "yyyy.mm.dd.hh.mm.ss"?
I know that 34 (date format code) is "yyyymmddhhmmss", but what about the code for "yyyy.mm.dd.hh.mm.ss"?
This is on SQL 2005.
CAST and CONVERT on MSDN says "no".
You have to CONVERT twice with styles 102 and 108, with a concatenation and REPLACE.
Where did you get the "34" date format code from?
As gbn said, using one of the existing formats with some string concatenation would work. Another option is:
SELECT
CAST(YEAR(my_date) AS CHAR(4)) + '.' +
RIGHT('0' + CAST(MONTH(my_date) AS VARCHAR(2)), 2) + '.' +
RIGHT('0' + CAST(DAY(my_date) AS VARCHAR(2)), 2) + '.' +
RIGHT('0' + CAST(DATEPART(HOUR, my_date) AS VARCHAR(2)), 2) + '.' +
RIGHT('0' + CAST(DATEPART(MINUTE, my_date) AS VARCHAR(2)), 2) + '.' +
RIGHT('0' + CAST(DATEPART(SECOND, my_date) AS VARCHAR(2)), 2)
Considering
SELECT CONVERT(VARCHAR(16), GETDATE(), 120) AS [YYYY-MM-DD]
---returns--- yyyy-mm-dd hh:ss
and you can use REPLACE to convert strings
REPLACE('a b c',' ','.')
----returns--- a.b.c
and you can recursively stack things you get to this
Select (
replace((replace((replace(CONVERT(VARCHAR(16), GETDATE(), 120),' ','.')), ':', '.')), '-', '.')
)
which returns: yyyy.mm.dd.hh.ss
works great for datetime stamps or filenames!