Posso usare l’istruzione CASE in una condizione JOIN?

L’immagine seguente fa parte delle visualizzazioni di sistema di Microsoft SQL Server 2008 R2. sys.partitions possiamo vedere che la relazione tra sys.partitions e sys.allocation_units dipende dal valore di sys.allocation_units.type . Quindi, per unirli insieme, scriverei qualcosa di simile a questo:

 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 

Ma il codice superiore dà un errore di syntax. Credo che sia a causa CASE . Qualcuno può aiutare a spiegare un po ‘?

Grazie!


Aggiungi un messaggio di errore:

Messaggio 102, livello 15, stato 1, riga 6 syntax errata vicino a ‘=’.

questa è l'immagine

Un’espressione CASE restituisce un valore dalla parte THEN della clausola. Potresti usarlo così:

 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 

Nota che devi fare qualcosa con il valore restituito, ad esempio confrontarlo con 1. La tua dichiarazione ha tentato di restituire il valore di un compito o di un test per l’uguaglianza, nessuno dei due ha senso nel contesto di una clausola CASE / THEN . (Se BOOLEAN fosse un tipo di dati, il test per l’uguaglianza avrebbe avuto senso).

Invece, basta unirsi a entrambe le tabelle e nella clausola SELECT, restituire i dati da quello che corrisponde:

Ti suggerisco di passare a questo link Conditional Joins in SQL Server e T-SQL Case Statement in una clausola JOIN ON

per esempio

  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 

Modifica: come da commenti.

Non è ansible specificare la condizione di join come si sta facendo .. Controllare la query sopra che non ha errori. Ho tirato fuori la colonna comune e il valore della colonna destra sarà valutato a condizione.

Prova questo:

 ...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) 

Questo sembra carino

https://bytes.com/topic/sql-server/answers/881862-joining-different-tables-based-condition

 FROM YourMainTable LEFT JOIN AirportCity DepCity ON @TravelType = 'A' and DepFrom = DepCity.Code LEFT JOIN AirportCity DepCity ON @TravelType = 'B' and SomeOtherColumn = SomeOtherColumnFromSomeOtherTable 

Qui ho confrontato la differenza in due diversi set di risultati. Spero che questo possa essere utile.

 SELECT main.ColumnName, compare.Value PreviousValue, main.Value CurrentValue FROM ( SELECT 'Name' AS ColumnName, 'John' as Value UNION ALL SELECT 'UserName' AS ColumnName, 'jh001' as Value UNION ALL SELECT 'Department' AS ColumnName, 'HR' as Value UNION ALL SELECT 'Phone' AS ColumnName, NULL as Value UNION ALL SELECT 'DOB' AS ColumnName, '1993-01-01' as Value UNION ALL SELECT 'CreateDate' AS ColumnName, '2017-01-01' as Value UNION ALL SELECT 'IsActive' AS ColumnName, '1' as Value ) main INNER JOIN ( SELECT 'Name' AS ColumnName, 'Rahul' as Value UNION ALL SELECT 'UserName' AS ColumnName, 'rh001' as Value UNION ALL SELECT 'Department' AS ColumnName, 'HR' as Value UNION ALL SELECT 'Phone' AS ColumnName, '01722112233' as Value UNION ALL SELECT 'DOB' AS ColumnName, '1993-01-01' as Value UNION ALL SELECT 'CreateDate' AS ColumnName, '2017-01-01' as Value UNION ALL SELECT 'IsActive' AS ColumnName, '1' as Value ) compare ON main.ColumnName = compare.ColumnName AND CASE WHEN main.Value IS NULL AND compare.Value IS NULL THEN 0 WHEN main.Value IS NULL AND compare.Value IS NOT NULL THEN 1 WHEN main.Value IS NOT NULL AND compare.Value IS NULL THEN 1 WHEN main.Value <> compare.Value THEN 1 END = 1 

Ho preso il tuo esempio e l’ho modificato:

 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 p.hobt_id WHEN a.type IN (2) THEN p.partition_id ELSE NULL END = a.container_id