SQL Switch / Case in 'where' -Klausel
-
03-07-2019 - |
Frage
Ich habe versucht, die Suche um, aber ich kann nichts finden, dass mir helfen würde.
Ich versuche, dies in SQL zu tun:
declare @locationType varchar(50);
declare @locationID int;
SELECT column1, column2
FROM viewWhatever
WHERE
CASE @locationType
WHEN 'location' THEN account_location = @locationID
WHEN 'area' THEN xxx_location_area = @locationID
WHEN 'division' THEN xxx_location_division = @locationID
Ich weiß, dass ich ‚= @locationID‘ am Ende eines jeden nicht setzen müssen, aber ich kann nicht die Syntax auch nur annähernd richtig sein bekommen. SQL hält auf der ersten über meine ‚=‘ beschweren, wenn die Leitung ...
Wie kann ich das tun?
Lösung
declare @locationType varchar(50);
declare @locationID int;
SELECT column1, column2
FROM viewWhatever
WHERE
@locationID =
CASE @locationType
WHEN 'location' THEN account_location
WHEN 'area' THEN xxx_location_area
WHEN 'division' THEN xxx_location_division
END
Andere Tipps
ohne einen Fall Aussage ...
SELECT column1, column2
FROM viewWhatever
WHERE
(@locationType = 'location' AND account_location = @locationID)
OR
(@locationType = 'area' AND xxx_location_area = @locationID)
OR
(@locationType = 'division' AND xxx_location_division = @locationID)
Hier gehen Sie.
SELECT
column1,
column2
FROM
viewWhatever
WHERE
CASE
WHEN @locationType = 'location' AND account_location = @locationID THEN 1
WHEN @locationType = 'area' AND xxx_location_area = @locationID THEN 1
WHEN @locationType = 'division' AND xxx_location_division = @locationID THEN 1
ELSE 0
END = 1
Ich würde sagen, dies ist ein Indikator für eine fehlerhafte Tabellenstruktur. Vielleicht sind die verschiedenen Standorttypen in verschiedenen Tabellen werden getrennt sollten, so dass Sie viel reicher Abfragen zu tun und auch um überflüssige Spalten vermeiden müssen.
Wenn Sie nicht in der Lage sind, die Struktur zu ändern, so etwas wie die folgenden funktionieren könnte:
SELECT
*
FROM
Test
WHERE
Account_Location = (
CASE LocationType
WHEN 'location' THEN @locationID
ELSE Account_Location
END
)
AND
Account_Location_Area = (
CASE LocationType
WHEN 'area' THEN @locationID
ELSE Account_Location_Area
END
)
Und so weiter ... Wir können nicht die Struktur der Abfrage im laufenden Betrieb ändern, aber wir können es außer Kraft setzen, indem sie die Prädikate gleich selbst aus.
EDIT: Die oben genannten Vorschläge natürlich viel besser sind, einfach ignorieren Mine
.Das Problem dabei ist, dass, wenn die SQL-Engine um den Ausdruck auszuwerten geht, überprüft er die FROM-Teil die richtigen Tabellen zu ziehen, und dann die WHERE-Teil einige Basiskriterien zur Verfügung zu stellen, so kann es nicht richtig einen dynamischen Zustand bewerten auf welche Spalte überprüfen gegen.
können Sie verwenden eine WHERE-Klausel, wenn Sie die WHERE Kriterien in das Prädikat sind die Überprüfung, wie
WHERE account_location = CASE @locationType
WHEN 'business' THEN 45
WHEN 'area' THEN 52
END
so in Ihrem speziellen Fall, Sie gehen die Abfrage in eine gespeicherte Prozedur setzen müssen oder drei separate Abfragen erstellen.
OR-Operator kann alternativ der Fall sein, wenn in dem Zustand
ALTER PROCEDURE [dbo].[RPT_340bClinicDrugInventorySummary]
-- Add the parameters for the stored procedure here
@ClinicId BIGINT = 0,
@selecttype int,
@selectedValue varchar (50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT
drugstock_drugname.n_cur_bal,drugname.cdrugname,clinic.cclinicname
FROM drugstock_drugname
INNER JOIN drugname ON drugstock_drugname.drugnameid_FK = drugname.drugnameid_PK
INNER JOIN drugstock_drugndc ON drugname.drugnameid_PK = drugstock_drugndc.drugnameid_FK
INNER JOIN drugndc ON drugstock_drugndc.drugndcid_FK = drugndc.drugid_PK
LEFT JOIN clinic ON drugstock_drugname.clinicid_FK = clinic.clinicid_PK
WHERE (@ClinicId = 0 AND 1 = 1)
OR (@ClinicId != 0 AND drugstock_drugname.clinicid_FK = @ClinicId)
-- Alternative Case When You can use OR
AND ((@selecttype = 1 AND 1 = 1)
OR (@selecttype = 2 AND drugname.drugnameid_PK = @selectedValue)
OR (@selecttype = 3 AND drugndc.drugid_PK = @selectedValue)
OR (@selecttype = 4 AND drugname.cdrugclass = 'C2')
OR (@selecttype = 5 AND LEFT(drugname.cdrugclass, 1) = 'C'))
ORDER BY clinic.cclinicname, drugname.cdrugname
END
Bitte versuchen Sie diese Abfrage. Antwort auf oben Beitrag:
select @msgID, account_id
from viewMailAccountsHeirachy
where
CASE @smartLocationType
WHEN 'store' THEN account_location
WHEN 'area' THEN xxx_location_area
WHEN 'division' THEN xxx_location_division
WHEN 'company' THEN xxx_location_company
END = @smartLocation
Versuchen Sie folgendes:
WHERE (
@smartLocationType IS NULL
OR account_location = (
CASE
WHEN @smartLocationType IS NOT NULL
THEN @smartLocationType
ELSE account_location
END
)
)
Case Statement in SQL Server Example
Syntax
CASE [ expression ]
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
...
WHEN condition_n THEN result_n
ELSE result
END
Example
SELECT contact_id,
CASE website_id
WHEN 1 THEN 'TechOnTheNet.com'
WHEN 2 THEN 'CheckYourMath.com'
ELSE 'BigActivities.com'
END
FROM contacts;
OR
SELECT contact_id,
CASE
WHEN website_id = 1 THEN 'TechOnTheNet.com'
WHEN website_id = 2 THEN 'CheckYourMath.com'
ELSE 'BigActivities.com'
END
FROM contacts;
Diese Abfrage. Es ist sehr einfach zu verstehen:
CREATE TABLE PersonsDetail(FirstName nvarchar(20), LastName nvarchar(20), GenderID int);
GO
INSERT INTO PersonsDetail VALUES(N'Gourav', N'Bhatia', 2),
(N'Ramesh', N'Kumar', 1),
(N'Ram', N'Lal', 2),
(N'Sunil', N'Kumar', 3),
(N'Sunny', N'Sehgal', 1),
(N'Malkeet', N'Shaoul', 3),
(N'Jassy', N'Sohal', 2);
GO
SELECT FirstName, LastName, Gender =
CASE GenderID
WHEN 1 THEN 'Male'
WHEN 2 THEN 'Female'
ELSE 'Unknown'
END
FROM PersonsDetail