1

私はアイテムの簡単なテーブルを持っています。それらを「パーツ」と呼びます。

各パーツは、個別のテーブルに 0 個以上の関連エントリを持つことができ、それらを「サブパーツ」と呼びます。おそらく予想されるように、テーブルの簡単なビューは次のとおりです。

Parts
-----
PartID int (PK)
PartName varchar

SubParts
--------
SubPartID int (PK)
PartID int (FK_Parts)
SubPartName varchar
SubPartAdded datetime

プライマリ テーブルからすべてのパーツを返したいのですが、存在する場合は LATEST (SubPartAdded DESC による順序) 関連の SubPart にもアクセスできます。

私の混乱は、subparts テーブルに (多くの異なるパーツに対して) 100 万以上のエントリがあり、存在する場合、現在のパーツの最新のものだけが必要であるということです。

前に、Parts テーブルと関連する Subparts の派生テーブルの間で左結合を実行するステートメントを作成しました (これは機能します) が、派生テーブルは subparts テーブルのすべての行を返すようで、パフォーマンス ヒットが発生します。PartID (およびその他の列) によってサブパーツを事前にフィルター処理するには、基本的に TOP 1 を実行し、派生した select ステートメントで DESC によって並べ替える必要があります。ただし、派生したselectステートメントで部品テーブル(外側)の列を参照できないように見えるため、派生テーブルにWHERE句を追加できません。

実行する次のスニペットも試しましたが、関連するレコードは返されません。

    SELECT  p.PartName, sp.SubPartName, sp.SubPartAdded
    FROM    Parts p 
    LEFT JOIN  (SELECT TOP 1 SubPartID, SubpartAdded, PartID FROM SubParts ORDER BY SubPartAdded) AS sp
               ON sp.PartID = p.PartID

「ON」ステートメントによってフィルタリングされる前に、「TOP 1」ステートメントが SubParts テーブル全体に対して実行されていると思います (?)

最終的には、メインのストアド プロシージャの複数の場所で Subparts テーブルのいくつかの列を使用する必要があるため、相関サブクエリを複数回呼び出す必要があるため、単純に相関サブクエリは必要ありません。

(この proc は、実行ごとに複数のパーツを返します。つまり、proc は単一の PartID によってフィルター処理されません)。

これがかなり明確であることを願っていますか?それは非常に単純な解決策を持つべきだと思われますが、私は現在困惑しています! (SQL Server 2K 以上との互換性が必要です)

よろしくニック

4

2 に答える 2

1

以下は、SQL Server 2000 に戻って動作するはずです。

SELECT  PartName, SubPartName, SubPartAdded
FROM    Parts
        LEFT JOIN
        (   SELECT  SubParts.PartID, SubParts.SubPartName SubParts.SubPartAdded
            FROM    SubParts
                    INNER JOIN
                    (   SELECT  PartID, MAX(SubPartAdded) [SubPartAdded]
                        FROM    SubParts
                        GROUP BY PartID
                    ) MaxSubPart
                        ON MaxSubPart.PartID = SubParts.PartID
                        AND MaxSubPart.SubPartAdded = SubParts.SubPartAdded
        ) Subpart
            ON SubPart.PartID = Parts.PartID

それ以降のバージョンでは、これを行うためのより効率的でエレガントな方法 (OUTER APPLY または Window 関数) がありますが、SQL Server 2000 と下位互換性がある方法がいくつあるかはわかりません。

于 2012-04-24T10:14:26.750 に答える
0

最後のサブパーツを抽出するには、派生テーブルが必要です。次に、id列とSubPartAdded列で派生テーブルに結合するサブパーツをフィルタリングできます。

SELECT  p.PartName, sp.SubPartName, sp.SubPartAdded
FROM    Parts p 
LEFT JOIN SubParts sp
  ON p.PartID = sp.PartID
LEFT JOIN 
(
  SELECT PartID, max (SubPartAdded) MaxSubPartAdded
    FROM SubParts 
   GROUP BY PartID
) AS MaxSP
  ON sp.PartID = MaxSP.PartID
 AND sp.SubPartAdded = MaxSP.MaxSubPartAdded

Sql Server 2005以降の場合:

SELECT  p.PartName, sp.SubPartName, sp.SubPartAdded
FROM    Parts p 
OUTER APPLY
(
   select top 1 
          SubPartName, SubPartAdded
     from SubParts 
    where SubParts.PartID = p.PartID
   order by SubPartAdded desc
) sp
于 2012-04-24T10:13:59.480 に答える