3

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.

2
  • 1
    Already answered see this post: stackoverflow.com/questions/1947753/… Commented Sep 24, 2012 at 17:10
  • The Oracle LEAST function will return the least of two or more values. I came here searching for an alternative to Oracle's LEAST, and all I find here is how to get the least of two values. I'm going to have to look elsewhere for a solution. Commented Jan 24, 2017 at 21:35

4 Answers 4

7

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' 
Sign up to request clarification or add additional context in comments.

4 Comments

Interesting, but requires SQL 2008 or higher. The OP did not specify. See msdn.microsoft.com/en-us/library/dd776382.aspx
Agreed with @Matt but, the concept is important, not the syntax. If the OP is using a specific legacy version, they should say so. Easy enough to re-write this using union to cater for that.
Okay, if you need to reference it in the WHERE clause, put the first select in a CTE or a CROSS APPLY.
SELECT MIN(dt) FROM (VALUES((SELECT max(CreateDate) FROM Customers (NOLOCK))), ((SELECT max(CreateDate) FROM LinkedServ.x.dbo.Customers))) dtlist(dt);
4

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);

Comments

1

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'

Comments

1

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.

2 Comments

So you're going to call a multi-statement scalar function twice for every row? Ouch.
The OP didn't give any mention to the size of the data, but I suppose you are right - as a general purpose function this would be rather slow on large data. It could be optimized to a table valued udf (sqlmag.com/article/sql-server/inline-scalar-functions) but then you might as well just do it inline anyway since there's so much involved in calling it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.