Kan jeg bruke CASE-setningen i en JOIN-betingelse?

Følgende bilde er en del av Microsoft SQL Server 2008 R2 System Views. Fra bildet kan vi se at forholdet mellom sys.partitions og sys.allocation_units avhenger av verdien av sys.allocation_units.type. Så for å bli med dem sammen ville jeg skrive noe som ligner på dette:

SELECT  *
FROM    sys.indexes i
        JOIN sys.partitions p
            ON i.index_id = p.index_id 
        JOIN sys.allocation_units a
            ON CASE
               WHEN a.type IN (1, 3)
                   THEN a.container_id = p.hobt_id 
               WHEN a.type IN (2)
                   THEN a.container_id = p.partition_id
               END 

Men den øvre koden gir en syntaksfeil. Jeg antar at det er på grunn av CASE-setningen. Kan noen hjelpe til med å forklare litt?


Legg til feilmelding:

Msg 102, nivå 15, tilstand 1, linje 6 Feil syntaks i nærheten av '='.

Dette er bildet]1.

Løsning

Et CASE uttrykk returnerer en verdi fra THEN delen av klausulen. Du kan bruke det på denne måten:

SELECT  * 
FROM    sys.indexes i 
    JOIN sys.partitions p 
        ON i.index_id = p.index_id  
    JOIN sys.allocation_units a 
        ON CASE 
           WHEN a.type IN (1, 3) AND a.container_id = p.hobt_id THEN 1
           WHEN a.type IN (2) AND a.container_id = p.partition_id THEN 1
           ELSE 0
           END = 1

Merk at du må gjøre noe med den returnerte verdien, f.eks. sammenligne den med 1. Din setning forsøkte å returnere verdien av en tilordning eller teste for likhet, og ingen av disse gir mening i sammenheng med en CASE/THEN-setning. (Hvis BOOLEAN var en datatype, ville testen for likhet gi mening).

Kommentarer (6)

I stedet gjør du ganske enkelt JOIN til begge tabellene, og i SELECT-klausulen,

returnere data fra den som samsvarer:

Jeg foreslår at du går gjennom denne lenken Betingede sammenføyninger i SQL Server og https://stackoverflow.com/questions/8361183/t-sql-case-statement-in-a-join-on-clause

f.eks.

    SELECT  *
FROM    sys.indexes i
        JOIN sys.partitions p
            ON i.index_id = p.index_id 
        JOIN sys.allocation_units a
            ON a.container_id =
            CASE
               WHEN a.type IN (1, 3)
                   THEN  p.hobt_id 
               WHEN a.type IN (2)
                   THEN p.partition_id
               END 

Rediger: I henhold til kommentarer.

Du kan ikke spesifisere sammenføyningsbetingelsen slik du gjør ... Sjekk spørringen ovenfor som ikke har noen feil. Jeg har tatt ut den vanlige kolonnen opp og den høyre kolonneverdien vil bli evaluert på betingelse.

Kommentarer (9)

Prøv dette:

...JOIN sys.allocation_units a ON 
  (a.type=2 AND a.container_id = p.partition_id)
  OR (a.type IN (1, 3) AND a.container_id = p.hobt_id)
Kommentarer (1)