My thought is thatSELECT @CanBackOrder=CASE WHEN CanBackOrder='Yes' THEN 1 ELSE 0 END FROM Customers WHERE CustomerID=@CustomerID
will be called every time, but that value is only needed when one, or more, of the rows selected from PRODUCTS table has StockLevel = 0 (which is a very rare occurrence). So I would prefer not to derive that until it was found to be needed.I could do:SELECT Col1, Col2, ... [Button] = CASE WHEN StockLevel > 0 THEN 'Buy' WHEN EXISTS (SELECT * FROM FROM Customers WHERE CustomerID=@CustomerID AND CanBackOrder='Yes') AND P.CanBeBackedOrdered = 1 THEN 'BackOrder' ELSE 'Email when in stock' ENDFROM Products AS PWHERE ... logic to get me a "page" of 20 products ...
Will(SELECT * FROM FROM Customers WHERE CustomerID=@CustomerID AND CanBackOrder='Yes')
only be executed once? or once-per-row in Products? (which would be bad!)and will it never be executed if all rows selected from PRODUCTS have "StockLevel > 0" (which would be true 99% of the time)A potentially further problem is that this code needs to exists in lots of places, therefore I would like to put in a Function, but that would potentially make the query less efficient.One thought I have had is to resolveDECLARE @CanBackOrder bitSELECT @CanBackOrder=CASE WHEN CanBackOrder='Yes' THEN 1 ELSE 0 END FROM Customers WHERE CustomerID=@CustomerID
for the Session, and store it in the session variables, and then pass it as a parameter to the Sproc - which would remove the need for any lookup at this point. (Still the issue that Products.CanBeBackedOrdered is not as simple as a single column lookup, there are other rules at play, most of which won't apply most of the time. I'll have a ponder whether I could move any of them to the Application variables and thus only calculate them once per Application.)