I am trying to create SQL that will select rows based on user input. One of the options will be for the user to select all rows.
Consider this sample:
WITH CTE_PROMPT AS (
SELECT 'M' Gender
),
CTE_DATA AS (
SELECT PERSON_NUMBER
,SEX
FROM Employees
)
SELECT CTE_DATA.*
FROM CTE_DATA
LEFT OUTER JOIN CTE_PROMPT ON CTE_DATA.Sex = CTE_PROMPT.Gender
WHERE CASE
WHEN Gender = 'ALL' THEN 1
WHEN Gender = SEX THEN 1
ELSE 0
END = 1
The correct results are shown when the user selects 'M' or 'F', but nothing is shown if the user selects 'ALL'. How do I write the SQL so that the 'ALL' option shows all records?
I would suggest against a CASE
expression as the clause won't be SARGable and instead use an OR
. As, however, the statement would easily suffer from parameter sniffing, I would then add a RECOMPILE
to the OPTION
clause.
This results in the following:
SELECT E.PERSON_NUMBER, --Why CAPITALS for columns, but Pascal for objects?
E.SEX
FROM dbo.Employees E
WHERE E.SEX = @Gender --An actual parameter, not a CTE
OR @Gender = 'All'
OPTION (RECOMPILE);