it-swarm.com.de

SQL Switch / Case in der 'where'-Klausel

Ich habe versucht, mich umzusehen, aber ich konnte nichts finden, was 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 nicht '= @LocationID' am Ende eines jeden setzen muss, aber ich kann die Syntax nicht annähernd richtig verstehen. SQL beschwert sich immer wieder über mein '=' in der ersten WHEN-Zeile ...

Wie kann ich das machen?

141
Miles
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
186
Bob Probst

ohne case 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)
69
Lukek

Bitte schön.

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
32
Pittsburgh DBA

Ich würde sagen, dies ist ein Indikator für eine fehlerhafte Tabellenstruktur. Möglicherweise sollten die verschiedenen Standorttypen in verschiedene Tabellen unterteilt werden, damit Sie umfangreichere Abfragen durchführen und auch überflüssige Spalten vermeiden können.

Wenn Sie die Struktur nicht ändern können, funktioniert möglicherweise Folgendes:

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 die Struktur der Abfrage im laufenden Betrieb nicht ändern, aber wir können sie außer Kraft setzen, indem wir die Prädikate einander angleichen.

EDIT: Die obigen Vorschläge sind natürlich viel besser, ignoriere nur meine.

6

Der OP-Operator kann eine Alternative sein, wenn sich der Patient in einem bestimmten Zustand befindet

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
5
atik sarker

Das Problem dabei ist, dass das SQL-Modul beim Auswerten des Ausdrucks den FROM-Teil überprüft, um die richtigen Tabellen abzurufen, und dann den WHERE-Teil, um einige Basiskriterien bereitzustellen, sodass es eine dynamische Bedingung für die Spalte nicht richtig auswerten kann prüfen gegen.

Sie können eine WHERE-Klausel verwenden, wenn Sie die WHERE-Kriterien im Prädikat überprüfen, z

WHERE account_location = CASE @locationType
                              WHEN 'business' THEN 45
                              WHEN 'area' THEN 52
                         END

in Ihrem speziellen Fall müssen Sie die Abfrage in eine gespeicherte Prozedur einfügen oder drei separate Abfragen erstellen.

5
Dillie-O

Bitte versuchen Sie diese Abfrage. Antwort auf obigen 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
3
Durre Najaf

Versuche dies:

WHERE (
    @smartLocationType IS NULL 
    OR account_location = (
         CASE
            WHEN @smartLocationType IS NOT NULL 
                 THEN @smartLocationType
            ELSE account_location 
         END
    )
)
2
shah134pk