If..Else or Case in WHERE Clause - something different - sql

I've read loads of q&a's on here but none fit the bill for what I'm trying to achieve.
I don't even know if this is possible! Any help/suggestions would be greatly appreciated.
I'm trying to build a conditional WHERE clause based on
CustID (int) = #CustomerID
If #CustomerID = 0 then I want the result to be WHERE CustID > 0 (i.e. return all customers) otherwise I only want certain customers CustID = #CustomerID
Is this possible?

Just do
WHERE (#CustomerID = 0 OR CustID = #CustomerID)

something like this?
SELECT *
FROM YOURTABLE
WHERE
( CASE
WHEN #CustomerID = 0 THEN CustID
ELSE 1
END
) > 0
AND
( CASE
WHEN #CustomerID <> 0 THEN #CustomerID
ELSE CUSTID
END
) = CUSTID

The most common way of simulating an IF-ELSE statement in sql are CASE and DECODE (in oracle at least):
Ex pseudocode:
if (x == 1) then y; else if (x == 2) then z; end if
CASE:
select
case x
when 1 then y
when 2 then z
end example
from dual;
DECODE:
select decode(x,1,y,2,z) example from dual;

Related

input parameter used in case statement in where clause

I have the following simplified stored procedure where based on on the input parameter, I need to then do a case in the where clause. It will not execute as it says: Incorrect syntax near '='
PROCEDURE [dbo].[DataInfo]
#Allowactive BIT = 1
AS
BEGIN
Select * from tbl1 1
where (CASE #Allowactive
WHEN 0 then (t.Isactive = 1) END
AND isSubmitted = 1
END
your where clause will be like below
where
CASE #Allowactive
WHEN 0 then t.Isactive END =1
AND isSubmitted = 1
You shouldn't use parameters in a query like this, as it messes up the query plan. When the right plan to use changes depending on the parameter, you need separate queries, or to force SQL to always recompile.
So do this instead:
create or alter procedure [dbo].[DataInfo] #Allowactive bit = 1
as
begin
if #Allowactive = 0
begin
Select * from tbl1 1
where Isactive = 1
AND isSubmitted = 1
end
else
begin
select * from tbl1 1
where isSubmitted = 1
end
end
Instead run separate queries.
Try to run the following and see the results:
SELECT *
FROM Tbl1 AS T
WHERE CASE #Allowactive
WHEN 0 THEN 1 ELSE #Allowactive END = T.Isactive
AND
isSubmitted = 1;
If you have 2012+ version then you could also do:
SELECT *
FROM Tbl1 AS T
WHERE IIF(#Allowactive = 0, 1, #Allowactive) = T.Isactive;
It seems Zaynul Abadin Tuhin directly answers your question.
But, I believe a case statement complicates what you want to achieve.
I think a query like this satisfies your desired outcome:
PROCEDURE [dbo].[DataInfo]
#Allowactive BIT = 1
AS
BEGIN
SELECT * FROM tbl1 t
WHERE (#Allowactive = 1 OR (#Allowactive = 0 AND t.Isactive = 1))
AND t.isSubmitted = 1
END

Choose multiple cases condition

I want to get multipule choises after then in case statment as
#value
select * from [dbo].[Currency_Tbl]
WHERE [Currency_Active_YN]=
CASE WHEN #value = 1 THEN
( 1 or 0)
ELSE
#Value = 0 then 0
END
it didn't accept the first line in col1 but accept the col2
how can I select multiple numbers after THEN?
You don't use case in where clauses. Use boolean logic
select * from [dbo].[Currency_Tbl]
WHERE (#value = 1 and [Currency_Active_YN] in (0,1))
OR (#value = 0 and [Currency_Active_YN] = 0)
You dont need a case to do what you're trying to do. Assuming Currency_Active_YN is a not null bit field the following logic should suffice.
select * from [dbo].[Currency_Tbl]
WHERE (#value=1 OR [Currency_Active_YN]=#Value)

Less expensive query?

I have a stored procedure that returns an integer 1 or 0 depending on specific criteria. It currently uses three select statements and it will be used heavily by multiple users across multiple locations. There has to be a more efficient way of doing this.
In short the query checks first to see if all checklist items on an order are completed (a separate table), then it checks to see if a field named BreakOutGuest (a bit field) is a 1 or 0. Depending on that result it checks to see if the total guest count is greater than 0 and the order total is zero. It returns the one or zero on all this criteria. Is there a more efficient way to do this? A temp table so I only have to hit the actual tables once? Below is the code.
#ORDERID INT
AS
BEGIN
DECLARE #AUTO_CLOSE INT
SET NOCOUNT ON;
--If all checklist items are marked complete move on, if not set #AUTO_CLOSE=0
IF NOT EXISTS(SELECT ORDERID FROM dbo.orderchecklistitems WHERE OrderID=#ORDERID AND CompletedON IS NULL)
BEGIN
--if BreakOutGuestFees is 1 only sum Guest_Count_1 + Guest_Count_2
IF EXISTS(SELECT * FROM dbo.Orders WHERE (GuestCount_1 + GuestCount_2)>1 AND OrderTotal=0 AND BreakoutGuestFees=1)
BEGIN
SET #AUTO_CLOSE=1
END
ELSE
SET #AUTO_CLOSE=0
--if BreakOutGuestFees is 0 only consider Guest_Count_1
IF EXISTS(SELECT * FROM dbo.Orders WHERE (GuestCount_1)>1 AND OrderTotal=0 AND BreakoutGuestFees=0)
BEGIN
SET #AUTO_CLOSE=1
END
ELSE
SET #AUTO_CLOSE=0
END
ELSE
SET #AUTO_CLOSE=0
END
If am not wrong you can combine two if clause into single if clause by using AND , OR logic. Try this.
IF NOT EXISTS(SELECT ORDERID
FROM dbo.orderchecklistitems
WHERE OrderID = #ORDERID
AND CompletedON IS NULL)
BEGIN
IF EXISTS(SELECT *
FROM dbo.Orders
WHERE ( ( GuestCount_1 + GuestCount_2 > 1
AND BreakoutGuestFees = 1 )
OR ( BreakoutGuestFees = 0
AND GuestCount_1 > 1 ) )
AND OrderTotal = 0
AND OrderID = #ORDERID)
SET #AUTO_CLOSE=1
ELSE
SET #AUTO_CLOSE=0
END
ELSE
SET #AUTO_CLOSE=0
You can perform your selection check with only one query
SELECT
(SELECT sum(1) FROM dual WHERE EXISTS (SELECT ORDERID FROM dbo.orderchecklistitems WHERE OrderID=#ORDERID AND CompletedON IS NULL)),
(SELECT sum(1) FROM dual WHERE EXISTS (SELECT 1 FROM dbo.Orders WHERE (GuestCount_1 + GuestCount_2)>1 AND OrderTotal=0 AND BreakoutGuestFees=1)),
(SELECT sum(1) FROM dual WHERE EXISTS (SELECT 1 FROM dbo.Orders WHERE (GuestCount_1)>1 AND OrderTotal=0 AND BreakoutGuestFees=0))
INTO
result1, result2, result3
from dual
then check results
DELCARE #AUTO_CLOSE INT = 0
IF NOT EXISTS(SELECT ORDERID
FROM dbo.orderchecklistitems
WHERE OrderID = #ORDERID
AND CompletedON IS NULL)
BEGIN
SET #AUTO_CLOSE =
(
SELECT
CASE
WHEN (GuestCount_1 + GuestCount_2 > 1) AND BreakoutGuestFees = 0 THEN 1
WHEN (GuestCount_1 > 1 ) AND BreakoutGuestFees = 1 THEN 1
ELSE 0 END
FROM dbo.orders
WHERE OrderTotal = 0 AND OrderID = #orderID
)
END

How to know if all the cells have the same value in some column

How to know if all the cells have the same value in some column (title changed)
I want to have a bit scalar value that tells me if all the values in a column equal something:
DECLARE #bit bit
SELECT #bit = TRUEFORALL(Name IS NOT NULL) FROM Contact
UPDATE
I now realized that I actually don't need the TrueForAll, what I do need is to make sure, that all values in a column are equal, for example, I want to know whether all Group.Items have the same price.
Why not?
select count( distinct price) from table
If returns 1, all values are the same... Add
where price is not null
if need be
For your updated requirement something like this would appear to do what you want:
DECLARE #IsSameGroup bit
SELECT #IsSameGroup = CASE WHEN COUNT(*) > 1 THEN 0 ELSE 1 END
FROM (SELECT Name FROM Contact GROUP BY Name) groups
When the count is greater the 1 you have two different names (or prices depending on what you group on)
Not very good for NULLs, but 2008 can do:
SELECT 1 WHERE 'Blue' = ALL ( SELECT Color FROM dbo.Hat )
OR
DECLARE #bit bit
SET #bit =
CASE ( SELECT 1 WHERE 'Blue' = ALL ( SELECT Color FROM dbo.Hat ))
WHEN 1 THEN 1 ELSE 0 END
UPDATE
All same color
SET #bit =
CASE(
SELECT 1 WHERE
(SELECT TOP(1) Color FROM dbo.Hat) = ALL ( SELECT Color FROM dbo.Hat )
)
WHEN 1 THEN 1 ELSE 0 END
Maybe this?
DECLARE #bit bit
if exists(SELECT Name FROM Contact WHERE Name IS NULL)
SET #bit = 0
ELSE
SET #bit = 1
This solves your first question:
SELECT
CASE
WHEN EXISTS(
SELECT 1
FROM Contact
WHERE Name IS NULL
) THEN 0
ELSE 1
END
ADDED:
This will solve your second:
SELECT
CASE
WHEN EXISTS(
SELECT TOP 1 1 FROM (
SELECT
ItemGroupName,
COUNT(Price) AS CNT
FROM ItemGroup
GROUP BY ItemGroupName
HAVING COUNT(Price) > 1
) t
) THEN 0
ELSE 1
END
By the way, when you use the exists function, its better to SELECT 1 (a constant) so less data gets returned

sub query with parameter?

I'd like to ask help on this small query of mine. Im doing a query and a sub query on my sub query i want to have it parameterized. Is there a way to do it?
Please see my query script.
select sum(issue) as [Issue], sum(nonissue) as [NonIssue]
from
(
AS
select
case when isissue = 1 then 1 else 0 end as 'issue',
case when isissue = 0 then 1 else 0 end as 'nonissue',
LastTicketStatusID
from
vw_Tickets
where
LastTicketStatusID = #LastTicketStatusID
)
as Tickets
I always got an error Must declare the table variable "#LastTicketStatusID". where should i declare the parameter?
Thanks,
Nhoyti
If this is for a stored procedure...
CREATE PROCEDURE [dbo].[ProcedureName]
#LastTicketStatusID INT
AS
select
sum(issue) as [Issue],
sum(nonissue) as [NonIssue]
from (
select
case when isissue = 1
then 1 else 0 end as 'issue',
case when isissue = 0
then 1 else 0 end as 'nonissue',
LastTicketStatusID
from vw_Tickets
where LastTicketStatusID = #LastTicketStatusID ) as Tickets
Otherwise
DECLARE #LastTicketStatusID INT
SELECT #LastTicketStatusID = yourDesiredID
Not pertinant to your question, but assuming that vw_Tickets.isissue is a bit field (or otherwise constrained to values of zero or one.) the inline query can be removed to simplify Launchy's answer:
select sum(isissue) as [Issue],
sum(1 - isissue) as [NonIssue]
from vw_Tickets
where LastTicketStatusID = #LastTicketStatusID
at the very top of the query
Declare #LastTicketStatusID int
set #lastTicketStatusID = ####