2017-06-12 5 views
0

4つの文字コードとその説明を持つテーブルがあります。 私は、単一の文字列に複数のエラーコードを持つ販売テーブルを持っています。 2つ以上のエラーの重みが互いに同じで、複数の結合された行を作成する場合を除いて、最高の重み付きエラーコードが結合されるようにするlikeを使用して結合を設計しました。部分文字列のSQL結合で、サブクエリで最大値を持つレコードが多すぎます

重みが等しい場合、私はちょうど

表のerrorCode

Code | Description  | Weight 
'0041' | 'data error'  | 4 
'0019' | 'format error' | 2 
'0099' | 'missing creator' | 2 

TABLE MyDataに私が手

ID | RespCode  
1234 | '00410019' 
1235 | '00990019' 

結果

ID | RespCode | Description 
1234 | '00410019' | 'data error' 
1235 | '00990019' | 'format error' 
1235 | '00990019' | 'missing creator' 
(いずれかが行います)1件の結果が欲しいです

私は1235のために1つの結果しか望んでいませんが、サブ選択でMaxまたはTop 1を使用しても、私は2つを取得します。どのようにして結合された行を1つに制限できますか?

SELECT * FROM MyData 
    left JOIN ErrorCodes 
    ON  MyData.RespCode 
    LIKE '%' + ErrorCodes.Code + '%' 
    AND ErrorCodes.Weight = ( 
     SELECT MAX (Weight) FROM ErrorCodes 
     WHERE MyDate.RespCode LIKE '%' + ErrorCodes.Code + '%' 
    ) 

答えて

1
SELECT 
    ID, RespCode, Description 
FROM 
(
    SELECT 
    ID, 
    RespCode, 
    Description, 
    ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Weight DESC) as rown 
    FROM 
    MyData 
    LEFT JOIN 
    ErrorCodes 
    ON 
     MyData.RespCode LIKE '%' + ErrorCodes.Code + '%' 
) a 
WHERE 
    rown = 1 

は、このためのSQL文(2008+)の最新バージョンが必要です。重複したすべての行IDを使用して問合せを行い、SQLサーバーにインプレース集計(パーティション単位)と行番号付けを依頼します。それはIDごとに1、2、3などをカウントするカウンタを与え、カウンタはIDの変更時に(パーティションのおかげで)再開し、カウントする行は重みの降順で並べ替えられます(より高い重みは最初に

その後、我々はただ単にROWN列とどのようにそれが

に動作を確認するために、括弧の間に1つを強調表示し、それを実行し、私は内側のクエリについて何を意味するかを確認するには、カウンタが1

ある行のみを選択します

注:Shawnのクエリは多かれ少なかれ同じであることが分かりました(申し訳ありませんShawn、私は鉱山を書いた後、あなたのクエリをよく見ていましたが、長い行のためにウィンドウ機能がスクリーンから外れていたためです)、余分な不要なサブクエリ、したがって、彼のpartiton/order by節は間違っています(ASCのおかげで最も軽い重み付けが選択されています。最高の重み付けが優先されたかったです)

+0

恐ろしいです!これはまさに私が必要としていたものです! –

+0

ようこそ..ウインドウ/分析クエリーは、頑張ったOracleの仕事をしているときに私が学んだ最も有用なものの1つで、2005年にSQLSを使用するように切り替えると、MSが指を引き出して入れておくのを3年(そして、私の職場が実際にSQLS 2005を現代的なものにアップグレードしている間、別の痛い5年を待つ)。お友達が先導/出血している場合、あなたは最も幸運です! :) –

0

救助にクエリ

SELECT * FROM MyData 
    left JOIN ErrorCodes 
    ON  MyData.RespCode 
    LIKE '' + ErrorCodes.Code + '%' 
    AND ErrorCodes.Weight = ( 
     SELECT MAX (Weight) FROM ErrorCodes 
     WHERE MyDate.RespCode LIKE '%' + ErrorCodes.Code + '%' 
    ) 
+0

これは '%'を '実際には、RespCodeの上位の重み付けコードが2番目の場合にクエリが中断されます。同様に、 '00410019'が '00190041'のように表示されている場合は、結果は無効です。 –

1

ウィンドウ関数以下の使用! :-)

SELECT ec2.ID, ec2.RespCode, ec2.[Description] 
FROM (
    SELECT ec1.ID, ec1.RespCode, ec1.Code, ec1.[Description], ec1.[Weight] , ROW_NUMBER() OVER (PARTITION BY ec1.ID ORDER BY ec1.[Weight] ASC) AS rn 
    FROM (
     SELECT 
       md.id 
      , md.RespCode 
      , ec.Code 
      , ec.[Description] 
      , ec.[Weight] 

     FROM #myData md 
     LEFT OUTER JOIN #ErrorCodes ec ON md.RespCode LIKE '%' + ec.Code + '%' 
    ) ec1 
) ec2 
WHERE ec2.rn = 1 
関連する問題