Μπορώ να χρησιμοποιήσω τη δήλωση CASE σε μια συνθήκη JOIN;

Η παρακάτω εικόνα αποτελεί μέρος των προβολών συστήματος του Microsoft SQL Server 2008 R2. Από την εικόνα μπορούμε να δούμε ότι η σχέση μεταξύ των sys.partitions και sys.allocation_units εξαρτάται από την τιμή του sys.allocation_units.type. Έτσι για να τα ενώσω μεταξύ τους θα έγραφα κάτι παρόμοιο με αυτό:

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 

Αλλά ο ανώτερος κώδικας δίνει συντακτικό σφάλμα. Υποθέτω ότι αυτό οφείλεται στη δήλωση CASE. Μπορεί κάποιος να βοηθήσει να εξηγήσει λίγο;


Προσθήκη μηνύματος σφάλματος:

Msg 102, Level 15, State 1, Line 6 Incorrect syntax near '='.

Λύση

Μια έκφραση CASE επιστρέφει μια τιμή από το τμήμα THEN της ρήτρας. Θα μπορούσατε να τη χρησιμοποιήσετε ως εξής:

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

Σημειώστε ότι πρέπει να κάνετε κάτι με την επιστρεφόμενη τιμή, π.χ. να τη συγκρίνετε με το 1. Η δήλωσή σας προσπάθησε να επιστρέψει την τιμή μιας ανάθεσης ή να ελέγξει την ισότητα, τίποτα από τα οποία δεν έχει νόημα στο πλαίσιο μιας ρήτρας CASE/THEN. (Αν το BOOLEAN ήταν τύπος δεδομένων, τότε ο έλεγχος ισότητας θα είχε νόημα).

Σχόλια (6)

Αντ' αυτού, απλά κάνετε JOIN και στους δύο πίνακες και στη ρήτρα SELECT, επιστρέφετε δεδομένα από αυτόν που ταιριάζει:

Σας προτείνω να διαβάσετε αυτόν τον σύνδεσμο Conditional Joins in SQL Server και https://stackoverflow.com/questions/8361183/t-sql-case-statement-in-a-join-on-clause.

π.χ.

    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 

Επεξεργασία: Σύμφωνα με τα σχόλια.

Δεν μπορείτε να καθορίσετε τη συνθήκη σύνδεσης όπως κάνετε.. Ελέγξτε το το παραπάνω ερώτημα που δεν έχει σφάλμα. Έχω αφαιρέσει την κοινή στήλη

και η τιμή της δεξιάς στήλης θα αξιολογηθεί με βάση τη συνθήκη.

Σχόλια (9)

Δοκιμάστε αυτό:

...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)
Σχόλια (1)