sql >> Base de Datos >  >> RDS >> Sqlserver

Compara dos filas e identifica columnas cuyos valores son diferentes

Tu dices:

 We want to highlight the parameters that have changed since the last revision.

Esto implica que desea que la pantalla (o el informe) haga que se destaquen los parámetros que cambiaron.

Si va a mostrar todos los parámetros de todos modos, sería mucho más fácil hacerlo mediante programación en la interfaz. Sería un problema mucho más simple en un lenguaje de programación. Desafortunadamente, al no saber cuál es su front-end, no puedo darle recomendaciones particulares.

Si realmente no puede hacerlo en el front-end pero tiene que recibir esta información en una consulta de la base de datos (usted dijo "solo SQL"), debe especificar el formato en el que desea los datos. A lista de una sola columna de las columnas que cambiaron entre los dos registros? Una lista de columnas con una bandera que indica qué columnas cambiaron o no.

Pero aquí hay una forma en que funcionaría, aunque en el proceso convierte todos sus campos en nvarchars antes de hacer su comparación:

  1. Utilice la técnica descrita aquí (descargo de responsabilidad:ese es mi blog) para transformar sus registros en pares ID-nombre-valor.
  2. Une el conjunto de datos resultante a sí mismo en ID, para que puedas comparar los valores e imprimir los que han cambiado:

     with A as (    
    --  We're going to return the product ID, plus an XML version of the     
    --  entire record. 
    select  ID    
     ,   (
          Select  *          
          from    myTable          
          where   ID = pp.ID                            
          for xml auto, type) as X 
    from    myTable pp )
    , B as (    
    --  We're going to run an Xml query against the XML field, and transform it    
    --  into a series of name-value pairs.  But X2 will still be a single XML    
    --  field, associated with this ID.    
    select  Id        
       ,   X.query(         
           'for $f in myTable/@*          
           return         
           <data  name="{ local-name($f) }" value="{ data($f) }" />      
           ') 
           as X2 from A 
    )
    ,    C as (    
     --  We're going to run the Nodes function against the X2 field,  splitting     
     --  our list of "data" elements into individual nodes.  We will then use    
     -- the Value function to extract the name and value.   
     select B.ID as ID  
       ,   norm.data.value('@name', 'nvarchar(max)') as Name  
       ,   norm.data.value('@value', 'nvarchar(max)') as Value
    from B cross apply B.X2.nodes('/myTable') as norm(data))
    
    -- Select our results.
    
    select *
    from ( select * from C where ID = 123) C1
    full outer join ( select * from C where ID = 345) C2
        on C1.Name = c2.Name
    where c1.Value <> c2.Value 
      or  not (c1.Value is null and c2.Value is null)