2012-04-21 19 views
84

La siguiente imagen es parte de las vistas del sistema de Microsoft SQL Server 2008 R2. De la imagen podemos ver que la relación entre sys.partitions y sys.allocation_units depende del valor de sys.allocation_units.type. Entonces, para unirlos escribiría algo similar a esto:¿Puedo usar la instrucción CASE en una condición 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 

Pero el código superior da un error de sintaxis. Supongo que es por la declaración CASE. ¿Alguien puede ayudarme a explicar un poco?

Gracias!


Agregar mensaje de error:

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

this is the image

+13

¿Qué software usó para hacer este hermoso diagrama DB? – LearnByReading

Respuesta

145

A CASE expresión devuelve un valor de la porción THEN de la cláusula. Puede usarlo así:

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 

Tenga en cuenta que debe hacer algo con el valor devuelto, p. compárelo con 1. Su afirmación intentó devolver el valor de una tarea o una prueba de igualdad, ninguna de las cuales tiene sentido en el contexto de una cláusula CASE/THEN. (Si BOOLEAN era un tipo de datos a continuación, la prueba de igualdad tendría sentido.)

+0

@HABO gracias que trabajó para mí. ... pero el problema es que cuando hago esto, las condiciones se caen ... por favor dime, ¿cómo lo rompo? –

+1

@SagarTandel - Lo siento, no entiendo "hacer una caída" y "cómo lo rompo". ¿Podría aclarar su comentario? (Recientemente surgió de una inmersión en Saba. Podría ser el Nitrox.) – HABO

+0

Comprueba todas las condiciones que no deseo. Quiero que salga del caso una vez que coincida con una condición. –

13

Prueba esto:

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

Aunque funcionaría, la consulta en la pregunta parece perfectamente válida. Entonces todavía no explica qué está mal con el código de OP – zerkms

24

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

le sugiero que vaya a través de este enlace y Conditional Joins in SQL ServerT-SQL Case Statement in a JOIN ON Clause

p.

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 

Editar: Según los comentarios.

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

Esto no explica qué está mal con 'CASE' – zerkms

+0

pero eso explica sobre la unión condicional .. –

+0

¿qué' conditional join' significa? Cada unión (excluyendo cruz) es un condicional. ¿Cómo este caso es diferente de cualquier otro? Su muestra tiene unión interna con la condición, así como la consulta de OP se ha unido con la condición. – zerkms

0

Aquí he comparado la diferencia de dos conjuntos de resultados diferentes. Espero que esto pueda ser útil.

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 
Cuestiones relacionadas