I have a table with, say, preferred colors.
For every person, we store the favorite color and the effective date. If the person changes preference, we store the new one with a newer effective date.
Example:
name color eff_date
John Green 2014-03-07
Luis Red 2014-03-07
Luis Yellow 2015-05-02
Nina Blue 2015-07-06
If we want to take the current preferred color of Luis:
SELECT color
FROM fav_colors
WHERE name='Luis'
AND eff_date=( SELECT max(eff_date) FROM fav_colors WHERE name='Luis' )
Now we decide that persons can change their favorite color anytime, but the change will only be effective from 1st January. So even if Luis entered a record that says that his favorite color is Yellow, the query must return the old value (Red) until 1st January 2016.
SELECT color
FROM fav_colors
WHERE name='Luis'
AND eff_date=( SELECT max(eff_date) FROM fav_colors WHERE name='Luis' and eff_date < '1 jan 2015' )
This query seems ok, but will not return any record for Nina. The rules say that a newcomer can choose the favorite color immediately, without waiting for next 1st January.
In other words, "if possible, take a record from 1st January or earlier; if not possible, any record; take the most recent".
This is what I was able to write:
SELECT color
FROM fav_colors
WHERE name='Luis'
AND eff_date= ISNULL(
( SELECT max(eff_date) FROM fav_colors WHERE name='Luis' and eff_date < '1 jan 2015' ),
( SELECT max(eff_date) FROM fav_colors WHERE name='Luis' )
)
Is there a more elegant, or more efficient, way to achieve this result?
I have no control on the tables structure, they are from PeopleSoft.
If Nina made two selections this year I want to show the most recent one.
Best Answer
You can simplify the first and second query with
TOP / ORDER BY
:It won't however return anything for Nina. You could use another subquery and then combine them with either
UNION ALL
and one moreTOP
or withCOALESCE()
(orISNULL()
as in your query):If you want to do this check for more than one (or all of the) persons on the table, you can use
OUTER APPLY
, as @RobFarley's explains in his answer.)