sql >> Database >  >> RDS >> Sqlserver

Vergelijk twee rijen en identificeer kolommen waarvan de waarden verschillend zijn

Jij zegt:

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

Dit houdt in dat u wilt dat het display (of rapport) de gewijzigde parameters laat opvallen.

Als je toch alle parameters wilt laten zien, zou het een stuk eenvoudiger zijn om dit programmatisch in de front-end te doen. Het zou een veel eenvoudiger probleem zijn in een programmeertaal. Helaas, omdat ik niet weet wat je front-end is, kan ik je geen specifieke aanbevelingen geven.

Als je het echt niet aan de voorkant kunt doen, maar deze informatie in een query uit de database moet ontvangen (je zei wel "SQL-only"), dan moet je het formaat specificeren waarin je de gegevens wilt hebben. lijst met één kolom van de kolommen die tussen de twee records zijn gewijzigd? Een lijst met kolommen met een vlag die aangeeft welke kolommen wel of niet zijn gewijzigd?

Maar hier is een manier die zou werken, hoewel het in het proces al je velden naar nvarchars converteert voordat het zijn vergelijking doet:

  1. Gebruik de hier beschreven techniek (disclaimer:dat is mijn blog) om uw records om te zetten in ID-naam-waarde-paren.
  2. Voeg de resulterende dataset samen met zichzelf op ID, zodat u de waarden kunt vergelijken en de gewijzigde waarden kunt afdrukken:

     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)
    


  1. Hoe MySQL op Windows te installeren

  2. MySQL LEAST()-functie - Vind het kleinste argument in een lijst met argumenten

  3. Nullable DateTime uit de database halen

  4. Master High Availability Manager (MHA) is gecrasht! Wat moet ik nu doen?