How do I use GETDATE in a WHERE clause using single quotes? - sql-server

How do I use GETDATE() in a WHERE clause using single quotes? I have the following script:
SELECT DISTINCT
pm_requisition.a_requisition
,pm_requisition.a_req_description
,pm_requisition.rq_position_loc
,pm_requisition.rq_status_of_emp
,pm_applicant_rec.a_applicant_no
,pm_applicant_rec.aq_status_of_appl
,pm_applicant_rec.aq_apply_date
FROM
pm_requisition
LEFT OUTER JOIN pm_applicant_rec
ON pm_requisition.a_requisition = pm_applicant_rec.a_requisition
WHERE
pm_requisition.rq_status_of_req NOT IN (N'6', N'7')
AND pm_applicant_rec.aq_status_of_appl = N'N'
AND rq_position_loc = '3300'
AND pm_applicant_rec.aq_apply_date = CAST(GETDATE()AS datetime2) --('2021-03-30 00:00:00.000')
The dataset does not yield any data using the GETDATE() clause, but if I use today's date (commented out) with single quotes I get the correct dataset. I obviously can't put single quotes around CAST(GETDATE()AS datetime2). Am I missing something simple?

The reason your query does not work is that GETDATE() returns the current date and time, not the current date. As a result, the last line will never match, as you are comparing a date only with a date and time.
Your solution CAST(GETDATE() AS DATE) works is because it removes the time, which means you are now comparing a date with a date.
If you simplify your SQL to something like this :-
SELECT TOP 1 aq_apply_date,
GETDATE() [GETDATE]
FROM pm_applicant_rec;
you will see a result like this, so two different values, and clear why they do not match :-
aq_apply_date GETDATE
----------------------- -----------------------
2021-04-04 00:00:00.000 2021-04-04 14:32:15.507
You might see something slightly different depending on the datatype used for aq_apply_date.

Related

How to convert different date formats to single one in snowflake

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.

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

FUnctions on Datekey

I want MonthName and MonthNumber from Datekey variable EX:20141217. I need output as
Month Name: December MonthNumber: 12
I tried to convert Datekey into DateTime variable using expression
convert(datetime,convert(varchar(10),InvoiceCreateDateKey,120))
and top of it I used Month function to get MonthNumber.
MONTH(convert(datetime,convert(varchar(10),InvoiceCreateDateKey,120)))
and this following expression for MonthName
DATENAME(m,convert(datetime,convert(varchar(10),InvoiceCreateDateKey,120)))
I want to know are there any other functions in sql that I can use other than this complicated expressions? I want to simplify those expressions. Using above expressions my sql query is taking very very long time to execute.
Do you have a date dimension table in you database? It would add a join but would eliminate function calls and clean up complicated expressions. You could store the format you want as a column in this table for each date and join on date key. They are also very useful for aggregating data by various time slices. I used this to start mine: http://www.codeproject.com/Articles/647950/Create-and-Populate-Date-Dimension-for-Data-Wareho but there are other ones out there as well
You could use SUBSTRING to get the 5th and 6th characters of the Datekey string.
You can use 112 conversion for full date name
datename(month, convert(date, convert(nvarchar(10),InvoiceCreateDateKey), 112))
Also you can use datepart for getting month number
datepart(M,convert(date, convert(nvarchar(10),InvoiceCreateDateKey), 112))

SQL-Server Datetime in WHERE Clause Issue

enter image description hereI am creating a query of two values, a period number and the corresponding date. The periods are accounting periods that are similar but not identical to our months. The dates are largely correct, but there are a few inconsistencies that I thought I would clean up with a WHERE statement.
For example, the date 4/1/2015 belongs in period 3, but it shows up in both period 3 and period 4. To fix this, I thought that I would create a WHERE statement stating:
SELECT DISTINCT table1.period,
table1.datetime
FROM table1
WHERE table1.period <> 4 AND table1.datetime <> '4/1/2015'
This took away all of period 4 away instead of just the one I needed. I have also tried the datetime syntax:
AND table1.datetime <> '20150401 00:00:00.000'
Both syntaxes had the same results. I am fairly inexperienced at SQL and have always hated dealing with datetime values, so any help would be great.
-EDIT- Forgot to add single quotations to the first datetime WHERE clause.
Try following:
SELECT DISTINCT table1.period,
table1.datetime
FROM table1
WHERE CASE WHEN table1.period = 4 AND CONVERT(VARCHAR(8),table1.datetime,112) = '20150401' THEN 1 ELSE 0 END = 0
This only get rid of rows that both has period=4 and datetime=20150401, while your query first get rid of anything that has period=4(no matter what [datetime] is), then get rid of anything has datetime=20150401.
Did you say that period is a string field ? you mean a varchar ?
Also you want to check on the date part only, not the time ?
then you can try this
SELECT DISTINCT table1.period,
table1.datetime
FROM table1
WHERE table1.period <> '4'
AND convert(date, table1.datetime) <> '20150401'

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)

Resources