SQL Server nested query for time offset - sql-server

I am trying to offset the time in the column based on the time zone. I am trying to use this:
SELECT
SERIAL_NUMBER,
CONVERT(datetime, TIME_FROM)
AT TIME ZONE ('US Eastern Standard Time')
FROM
tmp_TestZone
which returns what I need, however each row in my table has record with specific time zone which can be any time zone. What I have to do is to replace 'US Eastern Standard Time' with a nested query that will pull the correct time zone for particular serial number. Time zone is stored in the last column which is TIMEZONE_LU.TZ
My table looks like this:
,[IP_ADDRESS]
,[NAME]
,[GROUP_NAME]
,[DEVICE_TYPE]
,[LINE_NAME]
,[DATE_FROM]
,[TIME_FROM]
,[TIME_TO]
,[fw]
,[bw]
,[SITE_NAME]
,[TZ]
I tried to build the query like this:
SELECT
SERIAL_NUMBER,
CONVERT(datetime, TIME_FROM)
AT TIME ZONE (SELECT TZ
FROM tmp_TestZone) NEW_TIME
FROM
tmp_TestZone
But I'm getting an error:
Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
How do I fix this?
The suggestion:
SELECT
SERIAL_NUMBER,
CONVERT(datetime, TIME_FROM)
AT TIME ZONE (SELECT TZ
FROM tmp_TestZone) NEW_TIME
FROM
tmp_TestZone
Would work however i just found that my timezones are not standardized.
I am going to try to use
SELECT SERIAL_NUMBER,
SWITCHOFFSET(TIME_FROM, '-05:00')
FROM tmp_TestZone2
Could you help me to replace '-05:00' from above code so ti reads values from UTC_offset column which are in exact format as '-05:00'
Thank you so much
Ok so here is the table:
SELECT [SERIAL_NUMBER]
,[IP_ADDRESS]
,[NAME]
,[GROUP_NAME]
,[DEVICE_TYPE]
,[LINE_NAME]
,[DATE_FROM]
,[TIME_FROM]
,[TIME_TO]
,[fw]
,[bw]
,[SITE_NAME]
,[TZ]
,[CC]
,[UTC_offset]
,[UTC_DST_offset]
FROM [VHA].[dbo].[tmp_TestZone2]
And here is the data of that table:
I have the columns TIME_FROM and TIME_TO that needs to be offset for UTC_Offset values.
So for the instance in the picture TIME_FROM (10:10:00) and TIME_TO (11:00:00) should be offset for -7:00 and so on for every row the TIME_FROM and TIME_TO should be offset for what ever value is in column UTC_Offset.

Try like this
SELECT
SERIAL_NUMBER,
CONVERT(datetime, TIME_FROM)
AT TIME ZONE temp.tz
FROM
tmp_TestZone AS temp;
This may help you.
Edited Question's answer:
If I understood your question correctly then please try below query to remove your Time Offset from the result...
SELECT SERIAL_NUMBER,
CONVERT(varchar(19),SWITCHOFFSET(TIME_FROM, '-05:00'),120) AS Result_date
FROM tmp_TestZone2
OR
SELECT SERIAL_NUMBER,
CONVERT(varchar(19),SWITCHOFFSET(TIME_FROM, UTC_offset),120) AS Result_date
FROM tmp_TestZone2
Maintain varchar(19) length according your DATETIME CONVERSION CODE (like 120).

Related

Epoch timestamp converted to datetime but how to sort records later on

I got my answer from Martin on how to convert epoch to date time but now I am facing another issue. How to do I filter records that are only entered today or some other date?
I created view with DATEADD(SECOND, Timing, '19700101') and want to filter out records.
select * from [dbo].[vw_records]
where Timing like '%23-10-2019%'
This way I am not able to query datetime based on that view. So as far the conversion it is good solution but for querying records not too good.
On other hand, maybe it is better to convert it in the table and then query results. hm...
Any suggestions please..
If you want rows from today, then use inclusive Date logic:
SELECT {Columns list}
FROM YourTable
WHERE DateColumn >= CONVERT(date, GETDATE())
AND DATECOLUMN < DATEADD(DAY, 1, CONVERT(date, GETDATE()));
For today, this'll return all rows on or after 2019-10-28T00:00:00:00.000 and before (but not including) 2019-10-29T00:00:00:00.000.

can we use if condition for compare 2 dates and display the row in sql server

I have 2 dates column, one is current date and the one is user define date, I have to display the specific row when the user define date is 2days greater than current date.
In the below code I try to display the row, when both dates are equal. But I don't know how display the row in sql.
I have following Columns,
Rid
DateTime (User define date and time)
Reminder
Description
CRDateTime (current date and time)
I have to set 3 condition.
if both dates are equal means that should be display,
if DateTime is 2 days before CRDate means I have to display that row,
if DateTime is 1 day before the CRdate means I have to display that row.
declare DateTime as datetime1;
select RId if CAST (DateTime as date) =CAST (#CRDateTime as date)
The IF...ELSE statement is a control-flow statement that allows you to execute or skip a statement block based on a specified condition.
For example:
IF Boolean_expression
BEGIN
-- Statement block executes when the Boolean expression is TRUE
END
ELSE
BEGIN
-- Statement block executes when the Boolean expression is FALSE
END
If you want to check something in your SQL Statements you should use the where clause.
It could be looking like:
SELECT * FROM `[YOUR_TABLE_NAME]` WHERE `DateTime` = `CRDateTime`
If you want to check the date in a 2 Day decade you can use the SQL DATEADD Function.
It lookse like:
SELECT DATEADD(day, +1, '2017/08/25') AS DateAdd;
Resault of this code is 2017/08/26
In your case it looks like this:
SELECT RId where DATEADD(day, +2, DateTime) = CRDateTime
--- EDIT SECTION: ---
EDIT 1:
All in one you can use this code here:
SELECT RId WHERE
`DateTime` = `CRDateTime` OR
DATEADD(day, +1, DateTime) = CRDateTime OR
DATEADD(day, +2, DateTime) = CRDateTime
As I understand you basically want to show all the records with in range of 2 days.
SELECT RId, DateTime, Reminder, Description, CRDateTime
WHERE CRDateTime BETWEEN DATETIME AND DATEADD(day, +2, DateTime)
Or you may try this
SELECT RId, DateTime, Reminder, Description, CRDateTime
WHERE DateTime BETWEEN DATEADD(day, -2, CRDateTime) AND CRDateTime
The question isn't clear. I assume the actual question is how to filter a table's rows between two dates.
Filtering in SQL (in any product) is the job of the WHERE clause, not IF. You can use the BETWEEN clause to select values in a range.
If both the table field and the query parameter are date variables, the query is easy :
CREATE TABLE table1
(
RId int PRIMARY KEY,
DateField date,
INDEX IX_Table1_Date (DateField)
)
declare #dateParam date='20190801';
SELECT RId
FROM table1
WHERE DateField BETWEEN dateadd(day,-2,#dateParam) AND #DateParam
This query will take advantage of the IX_Table1_Date index to speed up the search. Typically, applying any kind of function on a table field prevents the query engine from using any index that includes that field simply because the values stored in the index have no relation to the function's result.
If you use the date parameter to be the current date, just assign GETDATE() to it.
declare #dateParam date=GETDATE();
If the field isn't a date, you can cast it to date and still get a fast range query, because the query engine is fast enough to convert the cast to a range query.
SELECT RId
FROM table1
WHERE cast(DateField as date) BETWEEN dateadd(day,-2,#dateParam) AND #DateParam
If DateField is not a date-related type, eg it's a varchar, a) that's a serious bug and b) the server won't be able to use any indexes.
Casting the parameter values won't affect performance as they actual values are calculated before the query starts executing. The query becomes quite noisy though :
declare #dateParam datetime='20190801'
SELECT RId
FROM table1
WHERE cast(DateField as date)
BETWEEN dateadd(day,-2,cast(#dateParam as date)) AND cast(#DateParam as date)
That's why it's better to use the correct type for parameters

SQL update based on query results with two parameters

I've created a virtual table in SQL Server that has 28 days from the current date and each date has rows for time that range from 12-10 pm incremented by 15 min and another value to indicate that it's turned on/off for availability, so it would be something like this:
date time onoff
-------------------------------------------------
2015-04-08 12:00 1
2015-04-08 12:15 1
....continue until 22:00 then start next day
2015-04-09 12:00 1
..... continue for 28 days
I'd like to update the availability based on a query from another table which would return the date, start and end time...
So far I came up with this
update table1
set onoff = 0
where tbl1date in (select tbl2date from table2 where userid = 1)
The problem I'm having is adding in the between certain hours part of the equation and I'm not sure how to do something like this in SQL or how to even search for the answer based on not being able to word it properly...
Can someone help or point me in the right direction?
use a DATETIME, don't use separate DATE and TIME fields.
I think you should take a look at DATEDIFF (https://technet.microsoft.com/pl-pl/library/ms189794(v=sql.110).aspx) function.
Your where query could look like this:
update table1 set onoff = 0
where
DATEDIFF(minute, <MIN_RANGE>, tbl1date) >= 0 and
DATEDIFF(minute, tbl1date, <MAX_RANGE>) >= 0
How you calculate MIN_RANGE and MAX_RANGE depends on your table2 structure.
As suggested, if you have control over the structure, use datetime fields as they are easier to do the comparisons on. I'm going to assume you don't have control over the structure.
In order to compare the datetimes you need to create them from your separate date and times. You can either parse the time field for the hours and minutes and use DATEADD to add the appropriate offsets to the date, or you can use CONVERT to interpret a date time string as a date. Something like
CONVERT(datetime, SUBSTRING(CONVERT(varchar, tbl1date, 121), 1, 10) + ' ' + tbl1time, 121)
What this does is to convert the date to odbc cannonical format and throwaway the time part as it takes only the first 10 characters. Then it appends the time and interprets the whole string as a odbc cannonical datetime string. That format is yyyy-mm-dd hh:mi:ss.mmm. The hours are based on 24 hours. So if your times are in AM/PM format you're going to have to convert them.
If your other table has separate date and times you'd use a similar expression to combine them.
Once you have the datetimes you can do something like this
UPDATE table1
SET onoff = 0
WHERE <expression above> BETWEEN (SELECT min_value FROM table2) AND (SELECT max_value FROM table2)

Select condition on date for datetime field

I want to impose date condition on a date time field in SQL Server.
The datetime field is like this 2011-01-19 17:57:18.350 and when I execute below query it yields no results.
select top 1000 *
from [dbo].[RouteState]
where convert (date, logtime, 101) = '12-01-2015'
Can someone help me what's going wrong here?
There is no need to convert the datetime column to anything. Use a closed-open interval instead and change the format of your string literal to yyyymmmdd to make sure that SQL Server will interpret the date value in the same way regardless of regional and date format settings.
select top 1000 *
from [dbo].[RouteState]
where logtime >= '20150112' and
logtime < '20150113';
For more info on casting a column to date you can have a look at Cast to date is sargable but is it a good idea?

SQL Server Converting int to Date

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

Resources