CASE
WHEN @FilterBy = 5 AND d.TransactionTime >= CAST(@Value1 AS DATE)
AND d.TransactionTime <= CAST(@Value2 AS DATE) THEN 1
ELSE 0
END = 1
Transact-SQL stored procedure with conditional "AND" logic
-
18-07-2023 - |
Question
I'm working on a stored procedure that is used to filter a grid based on criteria entered by the user. Among the possible criteria they may choose to see transactions that were done between a certain begin and end date. I pass 4 input parameters to the proc - @ClientKey, the client requesting the info, @FilterBy (this is the selected value from a dropdown list in ASP.NET, and essentially tells the proc whether the user is selecting to filter by name, address, date, etc. In this case the @FilterBy value for date is 5), @Value1, which in this instance would be the begin date, and @Value2, which in this instance would be the end date.
In pseudo-code, what I want is:
SELECT ABunchOfColumns FROM SomeJoinedTables WHERE SomeCriteria AND CASE @FilterBy WHEN 5 THEN d.TransactionTime >= CAST(@Value1 AS Date) AND d.TransactionTime <= CAST(@Value2 AS Date)
Below is the full query. I hope that someone who is more savvy than me with SQL can sort out what I'm trying to do and offer a solution.
Thanks in advance!
@ClientKey int,
@FilterBy int,
@Value1 varchar(150),
@Value2 varchar(150)
AS BEGIN
SELECT d.pKey AS PaymentKey, d.CaseKey, d.InvoiceID, d.AuthorizationCode, d.TransactionID, d.PaymentType, d.Amount, d.ExpirationDate, d.CardType, d.BankName, d.AccountNumber,
d.AccountType, c.Name, c.Address1, c.City, c.State, c.Zip, cs.PAmount, cs.TranCode, cs.TranDate, cs.[Desc] AS PaymentDescription, cc.[Desc] AS ChargeCodeDescription,
d.TransactionTime, a.Name AS AssociationName, d.PaymentType, c.ClientPaymentID
FROM DebtorPayment d INNER JOIN Cases c
ON d.CaseKey = c.pKey
AND d.ClientKey = c.ClientKey
INNER JOIN CaseSumm cs
ON d.CaseKey = cs.CaseKey
AND d.pKey = cs.Batch
AND d.ClientKey = cs.ClientKey
INNER JOIN ChargeCodes cc
ON c.ClientKey = cc.ClientKey
AND cs.TranCode = cc.RefNum
INNER JOIN AssnCtrl a
ON c.AssnKey = a.pKey
WHERE c.ClientKey = @ClientKey
AND d.AmountAllocated > 0
AND d.TransactionStatus = 'Successful'
AND c.Address1 LIKE CASE
WHEN @FilterBy = 1 THEN '%' + @Value1 + '%'
ELSE c.Address1
END
AND d.Amount = CASE
WHEN @FilterBy = 2 THEN @Value1
ELSE d.Amount
END
AND a.pKey = CASE
WHEN @FilterBy = 3 THEN CAST(@Value1 AS INT)
ELSE a.pKey
END
AND c.ClientPaymentID = CASE
WHEN @FilterBy = 4 THEN @Value1
ELSE c.ClientPaymentID
END
<ProblemArea>
AND CASE @FilterBy
WHEN 5 THEN d.TransactionTime >= CAST(@Value1 AS Date) AND d.TransactionTime <= CAST(@Value2 AS Date)
END
</ProblemArea>
AND c.LName LIKE CASE
WHEN @FilterBy = 6 THEN '%' + @Value1 + '%'
ELSE c.LName
END
ORDER BY d.TransactionTime DESC
END
Solution
OTHER TIPS
Do you mean something like the following? You might find this link useful too. Haven't tested the code, just proposing idea - and writing code like this has always felt "wrong" to me - perhaps someone could offer better.
CREATE PROC MyProc
@ClientKey int,
@FilterBy int,
@Value1 varchar(150),
@Value2 varchar(150)
-- NB WITH RECOMPILE, see link (above)
WITH RECOMPILE AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM ...
WHERE
Col1 = CASE
WHEN @FilterBy = 1 THEN @Value1
ELSE Col1
END
AND
1 = CASE
WHEN @FilterBy = 2 AND Col2 > @Value1 AND Col3 < @Value2 THEN 1
WHEN @FilterBy = 2 AND NOT (Col2 > @Value1 AND Col3 < @Value2) THEN 0
ELSE 1
END
END