Kan ik een CASE statement gebruiken in een JOIN voorwaarde?

De volgende afbeelding is een onderdeel van Microsoft SQL Server 2008 R2 System Views. Uit de afbeelding kunnen we zien dat de relatie tussen sys.partitions en sys.allocation_units afhankelijk is van de waarde van sys.allocation_units.type. Dus om ze samen te voegen zou ik iets schrijven dat hier op lijkt:

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 

Maar de bovenste code geeft een syntaxis fout. Ik denk dat dat's vanwege het CASE statement. Kan iemand helpen om het een beetje uit te leggen?


Foutmelding toevoegen:

Msg 102, Level 15, State 1, Line 6 Onjuiste syntaxis bij '='.

Oplossing

Een CASE expressie retourneert een waarde uit het THEN gedeelte van de clausule. Je zou het zo kunnen gebruiken:

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 op dat je iets moet doen met de geretourneerde waarde, b.v. vergelijken met 1. Je verklaring probeerde de waarde van een toewijzing terug te geven of te testen op gelijkheid, wat geen van beide zinvol is in de context van een CASE/THEN clausule. (Als BOOLEAN een datatype was, dan zou de gelijkheidstest wel zinvol zijn).

Commentaren (6)

In plaats daarvan, JOIN je gewoon naar beide tabellen, en in uw SELECT-clausule, retourneer je gegevens van degene die overeenkomt:

Ik stel voor dat je deze link Conditional Joins in SQL Server doorneemt en https://stackoverflow.com/questions/8361183/t-sql-case-statement-in-a-join-on-clause

bijv.

    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 

Bewerken: Zoals in de opmerkingen.

U kunt de join voorwaarde niet specificeren zoals u doet.. Controleer de query hierboven die geen fout hebben. Ik heb uit de gemeenschappelijke kolom omhoog en de waarde van de rechter kolom zal worden geëvalueerd op voorwaarde.

Commentaren (9)

Probeer dit eens:

...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)
Commentaren (1)