2013-10-09 23 views
14

È possibile utilizzare case in dove nella clausola? Qualcosa di simile a questo:SQL use Istruzione CASE nella clausola WHERE IN

DECLARE @Status VARCHAR(50); 
SET @Status='published'; 

SELECT * FROM Product P  
WHERE P.Status IN (CASE WHEN @Status='published' THEN (1,3) 
            WHEN @Status='standby' THEN (2,5,9,6) 
            WHEN @Status='deleted' THEN (4,5,8,10) 
            ELSE (1,3) 
            END) 

Questo codice dà l'errore: sintassi in prossimità '' non corretto.

+0

qual è il tipo di P.Status? –

+0

Puoi usare 'case' in un' where', ma non così. 'Caso' deve restituire un valore per istruzione. –

+0

@MaryamArshi: il tipo di P.Status è int. – POIR

risposta

20

No, non è possibile utilizzare case e in come questo. Ma si può fare

SELECT * FROM Product P  
WHERE @Status='published' and P.Status IN (1,3) 
or @Status='standby' and P.Status IN (2,5,9,6) 
or @Status='deleted' and P.Status IN (4,5,8,10) 
or P.Status IN (1,3) 

BTW è possibile ridurre che per

SELECT * FROM Product P  
WHERE @Status='standby' and P.Status IN (2,5,9,6) 
or @Status='deleted' and P.Status IN (4,5,8,10) 
or P.Status IN (1,3) 

dal or P.Status IN (1,3) ti dà anche tutti i record di @Status='published' and P.Status IN (1,3)

+2

Non hai bisogno di parentesi attorno a ciascuna clausola "o"? Per esempio. oppure (@ Status = 'standby' e P.Status IN (2,5,9,6)) – dcp

+4

Non pensare di aver bisogno di parentesi, ma l'ultima istruzione 'o' restituirà risultati falsi ...Vedi questo violino: il secondo disco non deve essere restituito. http://sqlfiddle.com/#!3/9aef0/6 – sgeddes

9

Mi rendo conto che questo è stato risposto, ma c'è un piccolo problema con la soluzione accettata. Restituirà falsi positivi. Facile da risolvere:

SELECT * FROM Products P  
WHERE (@Status='published' and P.Status IN (1,3)) 
    or (@Status='standby' and P.Status IN (2,5,9,6)) 
    or (@Status='deleted' and P.Status IN (4,5,8,10)) 
    or (@Status not in ('published','standby','deleted') and P.Status IN (1,2)) 

parentesi non sono necessari (anche se forse più facile da leggere, quindi, il motivo per cui li ho incluso).

1
select * from Tran_LibraryBooksTrans LBT left join 
Tran_LibraryIssuedBooks LIB ON case WHEN LBT.IssuedTo='SN' AND 
LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 when LBT.IssuedTo='SM' 
AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 WHEN 
LBT.IssuedTo='BO' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 
ELSE 0 END`enter code here`select * from Tran_LibraryBooksTrans LBT 
left join Tran_LibraryIssuedBooks LIB ON case WHEN LBT.IssuedTo='SN' 
AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 when 
LBT.IssuedTo='SM' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 
WHEN LBT.IssuedTo='BO' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 
1 ELSE 0 END 
1

select * from Tran_LibraryBooksTrans LBT left join Tran_LibraryIssuedBooks caso LIB ON quando LBT.IssuedTo = 'SN' E LBT.LIBRARYTRANSID = LIB.LIBRARYTRANSID ALLORA 1 quando LBT.IssuedTo = 'SM' E LBT.LIBRARYTRANSID = LIB.LIBRARYTRANSID ALLORA 1 quando LBT.IssuedTo = 'BO' E LBT.LIBRARYTRANSID = LIB.LIBRARYTRANSID poi 1 ELSE 0 END

1

forse si può provare in questo modo

SELECT * FROM Product P WHERE (CASE WHEN @Status = 'published' THEN (CASE WHEN P.Status IN (1, 3) THEN 'TRUE' ELSE FALSE END) WHEN @Status = 'standby' THEN (CASE WHEN P.Status IN (2, 5, 9, 6) THEN 'TRUE' ELSE 'FALSE' END) WHEN @Status = 'deleted' THEN (CASE WHEN P.Status IN (4, 5, 8, 10) THEN 'TRUE' ELSE 'FALSE' END) ELSE (CASE WHEN P.Status IN (1, 3) THEN 'TRUE' ELSE 'FALSE' END) END) = 'TRUE'

In questo modo se @Status = 'pubblicato', la query controlla se P.Status è tra 1 o 3, restituirà TRUE altro 'FALSE'. Questo sarà abbinato con TRUE alla fine

Spero che aiuti.

1

credo che si può utilizzare un'istruzione caso in una clausola in cui, ecco come lo faccio:

Select 
ProductID 
OrderNo, 
OrderType, 
OrderLineNo 
From Order_Detail 
Where ProductID in (
Select Case when (@Varibale1 != '') 
then (Select ProductID from Product P Where .......) 
Else (Select ProductID from Product) 
End as ProductID 
) 

Questo metodo ha funzionato per me più e più volte. Provalo!