Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Porównaj dwa wiersze i zidentyfikuj kolumny, których wartości są różne

Mówisz:

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

Oznacza to, że chcesz, aby wyświetlacz (lub raport) wyróżniał zmienione parametry.

Jeśli i tak zamierzasz pokazać wszystkie parametry, znacznie łatwiej byłoby to zrobić programowo w interfejsie użytkownika. Byłby to znacznie prostszy problem w języku programowania. Niestety, nie wiedząc, jaki jest Twój frontend, nie mogę dać Ci konkretnych zaleceń.

Jeśli naprawdę nie możesz tego zrobić w interfejsie użytkownika, ale musisz otrzymać te informacje w zapytaniu z bazy danych (mówiłeś „tylko SQL”), musisz określić format, w którym chcesz uzyskać dane. jednokolumnowa lista kolumn, które zmieniły się między dwoma rekordami? Lista kolumn z flagą wskazującą, które kolumny uległy zmianie, a które nie?

Ale oto jeden sposób, który zadziała, chociaż w trakcie konwertuje wszystkie pola na nvarchary, zanim dokona porównania:

  1. Użyj techniki opisanej tutaj (zastrzeżenie:to mój blog), aby przekształcić swoje rekordy w pary identyfikator-nazwa-wartość.
  2. Połącz wynikowy zestaw danych ze sobą na ID, aby móc porównać wartości i wydrukować te, które uległy zmianie:

     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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wartość pola Concat do ciągu w SQL Server

  2. Zamień zduplikowane spacje na pojedynczą spację w T-SQL

  3. Jak zmienić numer sekwencyjny konta pocztowego bazy danych w profilu w programie SQL Server (T-SQL)

  4. Połącz HP-UX Itanium z SQL Server

  5. JSON_QUERY() Przykłady w SQL Server (T-SQL)