Use something like LEAST in T-SQL on a datetime field [duplicate] - sql

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Getting the minimum of two values in sql
Okay what I Have a table with two datetime fields and I want to select the rows where the oldest date is equal to some date variable. I saw the LEAST function used somewhere but I can't use this in T-SQL
I need something like this
SELECT LEAST(date1, date2) as theDate FROM theTable WHERE theDate = '2012-09-24'
but that will work in T-SQL. Also date1 or date2 can sometimes be null so that may be important to know.

The CASE solution others have provided works well for the case (no pun intended) of two values. For future reference, it becomes a bit unweildy for three or more values and you might then want to do something like this:
SELECT (SELECT MIN(mydate)
FROM (VALUES(date1),(date2),(date3)) mylist(mydate)
) AS theDate
FROM theTable
WHERE theDate = '2012-09-24'

There is no such function in T-SQL. Try:
SELECT theDate = CASE WHEN date1 < date2 THEN date1 ELSE date2 END FROM ... ;
To handle NULLs you may want:
SELECT theDate = NULLIF(CASE WHEN date1 < date2 THEN date1 ELSE date2 END, '20301231')
FROM
(
SELECT
date1 = COALESCE(date1, '20301231'),
date2 = COALESCE(date2, '20301231')
FROM ...
) AS x;
Also, you can't reference the alias theDate in the WHERE clause, it doesn't exist yet. You might want to say:
WHERE '20120924' IN (date1, date2);

You could use a case to mimic least, and a subquery so you can refer to the case result in the where clause:
select *
from (
select case
when date1 > date2 or date1 is null then date2
else date1
end as theDate
, *
from TheTable
)
where theDate = '2012-09-24'

While the other answers are indeed valid, here it is in the form of a UDF, which is closer to what you asked for:
CREATE FUNCTION [dbo].[LeastDate] (#d1 datetime, #d2 datetime)
RETURNS datetime
AS
BEGIN
DECLARE #least datetime
IF #d1 is null or #d2 is null
SET #least = null
ELSE IF #d1 < #d2
SET #least = #d1
ELSE
SET #least = #d2
RETURN #least
END
Usage:
SELECT dbo.LeastDate(date1, date2) as theDate
FROM theTable
WHERE dbo.LeastDate(date1, date2) = '2012-09-24'
Or you can use a nested select to do it one time only:
SELECT * FROM (
SELECT dbo.LeastDate(date1, date2) as theDate FROM theTable
) t
WHERE theDate = '2012-09-24'
Note that the choice of calling the function separately in the where clause or using a nested select is the same as it would be for any SQL function, not just this one.

Related

creating max date function using sql in databricks

I am writing queries in databricks using sql on views and would like to calculate max of dates of update timestamp column across multiple views. for instance i am joining table a with table b and would like to know max(a.updt_ts,b.updt_ts). since max function can not have more than one columns mentioned, i want to create a function. Any help is greatly appreciated.
below is what i have:
CREATE temporary FUNCTION ufnGetMaxDt (#Date1 DATETIME2,#Date2 DATETIME2)
BEGIN
DECLARE #ret DATETIME2
, #MinDt datetime2;
SET #MinDt = cast('1900-01-01' as datetime2);
IF (#Date1) is null SET #Date1 = #MinDt;
IF (#Date2) is null SET #Date2 = #MinDt;
SET #ret = CASE When #Date1 >= #Date2
Then #Date1
else #Date2
END;
IF (#ret IS NULL)
SET #ret = #MinDt; -- Dummy date
RETURN #ret;
END
GO
You could just use greatest? eg
SELECT *, GREATEST( date1, date2 ) xmax
FROM tmp
Or put them in an array, explode it and then max that? eg something like this:
%sql
WITH cte AS
(
SELECT *, EXPLODE( ARRAY( date1, date2 ) ) xmax
FROM tmp
)
SELECT MAX( xmax )
FROM cte
Seems a bit excessive when you can just use greatest though? It's also worth having a read through the list of Spark SQL built-in functions. You don't have to remember them all but at least if you know something is possible it's useful:
https://spark.apache.org/docs/2.3.0/api/sql/index.html

How to select dates in MSSQL

I am trying to writing a query which can return a result if date time column(fromdate) is either null or fromdate is before a current date. Here is my query:
select * from patients where from date =null OR from date <= cast(cast(getdate() as date)as datetime)
but this query returning empty result. Can someone confirm me both checking null OR before currentDate check in query is valid or not ?
---------Apply filter on more than 1 column:-----------
SELECT *
FROM patients
WHERE(fromDate = NULL
OR t1.fromDate <= CONVERT(DATE, GETDATE()))
AND (t1.toDate = NULL
OR t1.toDate >= CONVERT(DATE, GETDATE()));
I have a null column in todate in table but apply like this give me empty result
This will work for you
SELECT *
FROM patients
WHERE fromdate IS NULL
OR fromdate <= CONVERT(DATE, GETDATE());
You would do:
select p.*
from patients p
where p.fromdate is null or p.fromdate <= cast(getdate() as date);
Notes:
According to your question fromdate does not have a space in it.
The correct comparison for NULL is IS NULL, not = NULL.
There is no need to cast a date back to a datetime for the comparison.
Try this:
select * from patients where [fromdate] is null OR [fromdate] <= cast(getdate() as datetime)

WHERE clause condition checking for NULL

let's say I have a table with columns ID, Date1 and Date2 where Date2can be NULL. I now want to have an SQL statement that ignores Date2 if it is NULL.
So I need something like that:
SELECT *
FROM
[myTable]
WHERE
ID = #someId
AND Date1 <= GETDATE()
AND Date2 >= GETDATE() IF Date2 IS NOT NULL
So I want to check if Date2 is not NULL and then compare it with the current date. If it is NULL then I just want to ignore it.
Hope my request is clear and understandable.
Cheers
Simon
AND Date1 <= GETDATE()
AND (Date2 IS NULL OR Date2 >= GETDATE() )
or
AND Date1 <= GETDATE()
AND COALESCE(Date2, GETDATE()) >= GETDATE()-- which means : if Date2 IS NULL say Date2 = GETDATE()
AND (Date2 >= GETDATE() OR Date2 IS NULL)
You could do it this way:
ISNULL(Date2, GETDATE()) >= GETDATE()
Give this sql a try.
SELECT *
FROM yourtable
WHERE ID = #someId
AND Date1 <= GETDATE()
AND (Date2 IS NULL
AND Date2 >= GETDATE());
SELECT *
FROM
[myTable]
WHERE
ID = #someId
AND Date1 <= GETDATE()
AND Date2 NOT IS NULL
AND Date2 >= GETDATE();

How to compare data with a multiple selection in SQL Server?

I have these dates as example:
date1: 2013-01-01
date2: 2013-01-25
I need to create a procedure that will insert the product special offer in the database if date1 is between these 2 dates.
create procedure CreateOfferProduct(
#codP varchar(5),
#date1 date,
#date2 date,
)
as
if(not exists(
select * from OfferProducts
where Products.codP = #codP
and #date1 <= (select date2 from OfferProducts where codP = #codP)
)
)
begin
insert into OfferProducts(codP, date1, date2)
values(#codP, #date1, #date2);
end
But since
select date2 from Products where codP = #codP
returns multiple values it doesn't work. Any help is appreciated.
This is one way to insert multiple rows that don't already exist in the destination, instead of doing this row-by-row technique where you assign values to a variable (which is slower and inflexible).
INSERT dbo.OfferProducts(codP, date1, date2)
SELECT p.codP, #date, #date2
FROM dbo.Products AS p
WHERE codP = #codP
AND NOT EXISTS
(
SELECT 1 FROM dbo.OfferProducts
WHERE codP = p.codP
AND date2 >= #date1 -- this logic seems funny
);
If you show sample data and desired results, including existing data that you want excluded from the insert, we might be able to formulate better logic for you.
You are looking for the intersection of two time periods. The following may be what you want:
. . .
if not exists (
select *
from OfferProducts op
where op.codP = #codP and
(op.date1 <= #date2 and
op.date2 >= #date1)
)
. . .
The exact definition of overlap depends on whether the end points are included in the date range.
On re-reading the question, you explicitly state "if its date1 is between these 2 dates". If so, then try:
if not exists (
select *
from OfferProducts op
where op.codP = #codP and
op.date1 between #date1 and #date2
)
. . .

How to get date difference between two dates in same year with one date is from an input date not from the year

Well this is my case: I have an input date X (dd-mm-yyyy), and I want to count the number of days between it with the year part is changed into current year and today's date in SQL. I t comes with the following condition, after the year is changed temporarily: (Here's my current idea of the logic)
- If date X is earlier than today, then difference = datediff(X,now), with the X year is current year
- If date X is later than today, then difference = datediff(X,now), with the X year is one year before
Sample case:
1st case: The input date is 6-6-1990. Today (automatically generated) is 22-8-2011. Then the difference will be = datediff(6-6-2011,22-08-2011)
2nd case: The input date is 10-10-1990. Today (automatically generated) is 22-8-2011. Then the difference will be = datediff(10-10-2010,22-08-2011)
Any idea how to do this in SQL (in SQL Server)? Or is there any other more simple alternatives for this problem? I'd also like this to be done in the query and not using a stored procedure or function
Sorry if there's already a similar question, I just don't know the exact keyword for this problem :( if there's a question like this previously, feel free to direct me there.
Thanks in advance
Here is the implementation (if I understood the logic you need correctly):
USE YourDbName
GO
CREATE FUNCTION YearPartDiff (#date datetime)
RETURNS int
AS
BEGIN
DECLARE #dateCurrentYear datetime
SET #dateCurrentYear = DATEADD(year, YEAR(GETDATE()) - YEAR(#date), #date)
DECLARE #result int
IF #dateCurrentYear < GETDATE()
SET #result = ABS(DATEDIFF(day, #dateCurrentYear, GETDATE()))
ELSE
SET #result = ABS(DATEDIFF(day, DATEADD(year, -1, #dateCurrentYear), GETDATE()))
RETURN(#result)
END
GO
And the example of usage:
USE YourDbName
GO
DECLARE #someDate datetime
SET #someDate = '2011-06-06'
SELECT dbo.YearPartDiff(#someDate) /*returns 77*/
SET #someDate = '2010-10-10'
SELECT dbo.YearPartDiff(#someDate) /*returns 316*/
Basically, #Andrei's solution, but in a single statement:
SELECT
DayDiff = DATEDIFF(
DAY,
DATEADD(YEAR, CASE WHEN LastOcc > GETDATE() THEN -1 ELSE 0 END, LastOcc),
GETDATE()
)
FROM (
SELECT LastOcc = DATEADD(YEAR, YEAR(GETDATE()) - YEAR(#InputDate), #InputDate)
) s
This seems to do the job
SELECT DATEDIFF(DAY, CONVERT(DATETIME, N'2011-06-06'), CONVERT(DATETIME, N'2011-08-22'))
So the basic syntax is
SELECT DATEDIFF(DAY, CONVERT(DATETIME, N'yyyy-mm-dd'), CONVERT(DATETIME, N'yyyy-mm-dd '))
Alternatively, you can use GETDATE() instead of the string for today's date
I have used "SELECT DATEDIFF( D, "+myDate+", GETDATE())" in my code, on SQL Server 2005. It works for me. The value myDate of course would be the DateTime input value.
you should try this query:
create table #T (inp_date datetime)
insert #T values ('06-06-1990')
insert #T values ('08-22-1990')
insert #T values ('10-10-1990')
--select * from #T
select inp_date, GETDATE(),
CASE
WHEN DATEADD(yy,DATEDIFF(yy,inp_date,GETDATE()),inp_date) <= GETDATE()
THEN DATEDIFF(dd,DATEADD(yy,DATEDIFF(yy,inp_date,GETDATE()),inp_date),GETDATE())
ELSE DATEDIFF(dd,DATEADD(yy,DATEDIFF(yy,inp_date,GETDATE())-1,inp_date),GETDATE())
END
from #T