sql >> データベース >  >> RDS >> Sqlserver

2つの行を比較し、値が異なる列を特定します

    あなたが言う:

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

    これは、変更されたパラメータを目立たせるために表示(またはレポート)が必要であることを意味します。

    とにかくすべてのパラメーターを表示する場合は、フロントエンドでプログラムでこれを行う方がはるかに簡単です。プログラミング言語では、はるかに単純な問題になります。残念ながら、フロントエンドが何であるかわからないため、特定の推奨事項を提供することはできません。

    フロントエンドでは実際には実行できないが、データベースからのクエリでこの情報を受信する必要がある場合(「SQLのみ」と言った場合)、データを入力する形式を指定する必要があります。A 2つのレコード間で変更された列の単一列リスト?どの列が変更されたか、変更されなかったかを示すフラグが付いた列のリスト?

    ただし、これが機能する1つの方法ですが、プロセスでは、比較を行う前にすべてのフィールドをnvarcharsに変換します。

    1. ここで説明する手法(免責事項:これは私のブログです)を使用して、レコードをID-名前-値のペアに変換します。
    2. 結果のデータセットをIDでそれ自体に結合して、値を比較し、変更された値を出力できるようにします。

       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. MySQLでレストラン注文システムのデータベースを設計するためのガイド

    2. SQLServerのCPUパフォーマンスの問題のトラブルシューティング

    3. Oracle Database 12cの作成–ステップバイステップ

    4. Hadoop入出力システムを理解する