2012-04-21 13 views
84

L'immagine seguente fa parte delle viste del sistema Microsoft SQL Server 2008 R2. Dall'immagine 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:Posso usare l'istruzione CASE in una condizione JOIN?

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 genera un errore di sintassi. Suppongo che sia dovuto alla dichiarazione CASE. Qualcuno può aiutarmi a spiegare un po '?

Grazie!


Add messaggio di errore:

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

this is the image

+13

Quale software hai utilizzato per realizzare questo bellissimo diagramma DB? – LearnByReading

risposta

145

Un CASE espressione restituisce un valore dalla THEN porzione della clausola. Si può usare 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 

Si noti che è necessario fare qualcosa con il valore restituito, ad es. 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 era un tipo di dati, allora il test per l'uguaglianza avrebbe senso.)

+0

@HABO grazie che ha lavorato per me. ..ma il problema è quando faccio questo le condizioni fanno una caduta ... per favore dimmi come posso romperlo? –

+1

@SagarTandel - Scusate, non capisco "fare una caduta" e "come posso romperlo". Potresti chiarire il tuo commento? (Recentemente è emerso da un tuffo al largo di Saba. Potrebbe essere il Nitrox.) – HABO

+0

Controlla tutte le condizioni che non desidero. Voglio lasciare il caso una volta che corrisponde a una condizione. –

13

Prova questa:

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

Anche se funzionasse, la query nella domanda sembra perfettamente valida. Quindi continua a non spiegare cosa c'è di sbagliato nel codice OP – zerkms

24

Instead, you simply JOIN to both tables, and in your SELECT clause, return data from the one that matches:

vi consiglio di passare attraverso questo link Conditional Joins in SQL Server e T-SQL Case Statement in a JOIN ON Clause

ad es.

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.

You can not specify the join condition as you are doing.. Check the query above that have no error. I have take out the common column up and the right column value will be evaluated on condition.

+0

Questo non spiega cosa c'è di sbagliato in 'CASE' – zerkms

+0

ma questo spiega il join condizionale .. –

+0

cosa significa" join condizionale "? Ogni join (escluso cross) è un condizionale. In che modo questo caso è diverso da qualsiasi altro? Il tuo campione ha inner join con condition, così come la query di OP è entrato in condizione. – zerkms

0

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 
Problemi correlati