2

私は一連のデータを持っており、結合するフィールドとテーブルの数は非常に複雑ですが、この特定の問題に関する説明のために、ここで必要なフィールド/テーブルを使用して問題を抽出できると思います。

ClientData、Sources、Pricesの3つのテーブルがあります

最小値を選択する前の現在のクエリは次のようになります。

select c.RecordID, c.Description, s.Source, p.Price, p.Type, p.Weight
from ClientData c
inner join Sources s ON c.RecordID = s.RecordID
inner join Prices p ON s.SourceID = p.SourceID

これにより、次の結果が生成されます。

RecordID   Description        Source     Price  Type   Weight
=============================================================
001002003  ABC Common Stock   Vendor 1  104.5   Close  1
001002003  ABC Common Stock   Vendor 1  103     Bid    2
001002003  ABC Common Stock   Vendor 2  106     Close  1
001002003  ABC Common Stock   Vendor 2  100     Unknwn 0
111222333  DEF Preferred Stk  Vendor 3  80      Bid    2
111222333  DEF Preferred Stk  Vendor 3  82      Mid    3
111222333  DEF Preferred Stk  Vendor 2  81      Ask    4

私がやろうとしているのは、同じレコードに属し、そのレコードのゼロ以外の最小の重みを持つ価格を表示することです(したがって、重みは0より大きくなければなりませんが、残りの重みの中で最小でなければなりません)。したがって、上記の例では、レコード001002003の場合、ベンダー1とベンダー2の両方の重みが1(そのレコードの最小重み)であるため、それらの終値を表示したいと思います。しかし、111222333の場合、ベンダー3の重み2が最小であり、そのレコードのゼロ以外であるため、ベンダー3からの入札価格のみを表示したいと思います。私が求めている結果は次のとおりです。

RecordID   Description        Source     Price  Type   Weight
=============================================================
001002003  ABC Common Stock   Vendor 1  104.5   Close  1
001002003  ABC Common Stock   Vendor 2  106     Close  1
111222333  DEF Preferred Stk  Vendor 3  80      Bid    2

これを達成する方法について何かアイデアはありますか?

編集:これはSQL ServerCompactEdition用です。

4

3 に答える 3

2

私は解決策を思いつくことができたので、それを共有しようと思いました:

SELECT x.RecordID, VendorSource, VendorPrice
FROM ClientData x
INNER JOIN Sources s ON x.RecordID = s.RecordID
INNER JOIN Prices p ON s.SourceID = p.SourceID
INNER JOIN (SELECT c.RecordID, MIN(Weight) min_weight
            FROM ClientData c
            INNER JOIN Sources s ON c.RecordID = s.RecordID
            INNER JOIN Prices p ON s.SourceID = p.SourceID
            WHERE Weight != 0 
            GROUP BY c.RecordID) w ON x.RecordID = w.RecordID
WHERE p.Weight = w.min_weight

これにより、派生テーブルのRecordIDレベルに最小の重みを設定できるため、RecordIDごとに1つの重みがあります。

答えてくれたすべての人に感謝します。提供されたヘルプとガイダンスに感謝します。

于 2012-06-13T00:31:24.163 に答える
0

RecordId上のPartitionでRANK()を使用し、重みを増やして(ゼロの重みを完全に除外した後)各行を「評価」してから、上位にランク付けされた行を単純に除外できます。2番目のクエリを単純かつ明確に保つために使用されるCTE

;WITH MyRecords AS
(
    -- Your source query goes here
    select c.RecordID, c.Description, s.Source, p.Price, p.Type, p.Weight
    from ClientData c
    inner join Sources s ON c.RecordID = s.RecordID
    inner join Prices p ON s.SourceID = p.SourceID
)
SELECT RecordID, [Description], [Source], [Price], [Type], [Weight]
FROM
(
    SELECT RecordID, [Description], [Source], [Price], [Type], [Weight], 
           -- With ranking, the lower the weight the better
           Rnk = RANK() OVER (PARTITION BY RecordId ORDER BY [Weight] ASC)
    FROM MyRecords
    -- But exclude Weight 0 entirely
    WHERE [Weight] > 0
) RankedRecords
-- We just want the top ranked records, with ties
WHERE Rnk = 1

投稿後に追加された編集CE制約。Sql Server Compact EditionのSELECTステートメントでランク関数を複製するにはどうすればよいですか?を参照してください。CEでRANK()をシミュレートする方法について。

于 2012-06-06T04:26:20.377 に答える
0

実際にこれを思い通りに機能させるには、構造を少し変更する必要があると思います。基本的に、価格レコードは、ClientDataテーブルにあるように見えるアイテムではなくソースに対して設定されます。Sourcesテーブルからc.Recordnumber列を削除し、Pricesテーブルに配置することで、正しいOne(ClientData)to many(Prices)とOne(ClientData)to many(Sources)の関係を取得する必要があると思います。 。

select c.RecordID, c.Description, s.Source, p.Price, p.Type, p.Weight
from ClientData c
inner join Prices p ON c.RecordID = p.RecordID
inner join Sources s ON s.SourceID = p.SourceID
   AND p.Weight> 0
LEFT OUTER JOIN #Prices p2 ON c.RecordID = p2.RecordID
   AND p2.PriceID <> p.priceID
   AND p2.Weight > 0
   AND p2.Weight < p.Weight
WHERE p2.SourceID IS NULL

上記で指定した変更を行うと、このクエリは探している正確なデータを返します。

于 2012-06-06T04:15:55.160 に答える