9

2 つのテーブルの結合ビューを作成していますが、table2 から不要な重複が発生しています。
例: table1 には 9000 レコードがあり、結果のビューにまったく同じものを含める必要があります。table2 には同じ FKID を持つ複数のレコードが含まれている可能性がありますが、1 つのレコードのみを返したいと考えています (顧客はランダムに選択しても問題ありません)。正しく動作する次のコードがありますが、パフォーマンスが必要以上に遅くなります (14 秒以上)。

SELECT     
    OBJECTID
    , PKID
    ,(SELECT TOP (1) SUBDIVISIO
        FROM dbo.table2 AS t2
        WHERE (t1.PKID = t2.FKID)) AS ProjectName
    ,(SELECT TOP (1) ASBUILT1
        FROM dbo.table2 AS t2
        WHERE (t1.PKID = t2.FKID)) AS Asbuilt
FROM dbo.table1 AS t1

パフォーマンスを高速化するために結合で同様のことを行う方法はありますか?
SQL Server 2008 R2 を使用しています。
次のコード (~.5 秒) に近づきましたが、「Distinct」はすべての列が (FKID だけでなく) 重複している場合にのみレコードを除外します。

SELECT
    t1.OBJECTID
    ,t1.PKID
    ,t2.ProjectName
    ,t2.Asbuilt
FROM dbo.table1 AS t1
    LEFT JOIN (SELECT
        DISTINCT FKID
        ,ProjectName
        ,Asbuilt
        FROM dbo.table2) t2
    ON t1.PKID = t2.FKID

テーブルの例

table1          table2

OID, PKID       FKID, ProjectName, Asbuilt
1, id1          id1, P1, AB1
2, id2          id1, P5, AB5
3, id4          id2, P10, AB2
5, id5          id5, P4, AB4

上記の例では、返されるレコードは id5/P4/AB4、id2/P10/AB2、および (id1/P1/AB1 OR id1/P5/AB5) である必要があります。

私の検索では同様の質問が出てきましたが、問題を解決するものはありませんでした。 リンク,リンク
よろしくお願いします。これは私の最初の投稿なので、ルールを破っている場合はお知らせください。

4

3 に答える 3

14

This will give the results you requested and should have the best performance.

SELECT     
    OBJECTID
    , PKID
    , t2.SUBDIVISIO,
    , t2.ASBUILT1

FROM        dbo.table1 AS t1
OUTER APPLY (
    SELECT  TOP 1 *
    FROM    dbo.table2 AS t2
    WHERE   t1.PKID = t2.FKID
    ) AS t2
于 2013-01-30T22:41:57.300 に答える
3

元のクエリは、2 つの列に対して任意の値を生成しています ( topwith noの使用order by)。これで同じ効果を得ることができます:

SELECT t1.OBJECTID, t1.PKID, t2.ProjectName, t2.Asbuilt
FROM dbo.table1 t1 LEFT JOIN
     (SELECT FKID, min(ProjectName) as ProjectName, MIN(asBuilt) as AsBuilt
      FROM dbo.table2
      group by fkid
     ) t2
    ON t1.PKID = t2.FKID

このバージョンでは、 が に置き換えdistinctられgroup byます。

SQL Server で真にランダムな行を取得するには (構文が使用していることを示唆しています)、これを試してください。

SELECT t1.OBJECTID, t1.PKID, t2.ProjectName, t2.Asbuilt
FROM dbo.table1 t1 LEFT JOIN
     (SELECT FKID, ProjectName, AsBuilt,
             ROW_NUMBER() over (PARTITION by fkid order by newid()) as seqnum
      FROM dbo.table2
     ) t2
    ON t1.PKID = t2.FKID and t2.seqnum = 1

これは、バージョン 2005 以降を前提としています。

于 2013-01-30T22:32:03.860 に答える
1

説明した結果が必要な場合は、使用する必要がありINNER JOIN、次のクエリでニーズが満たされます。

SELECT
  t1.OID,
  t1.PKID,
  MAX(t2.ProjectName) AS ProjectName,
  MAX(t2.Asbuilt) AS Asbuilt
FROM table1 t1
JOIN table2 t2 ON t1.PKID = t2.FKID
GROUP BY
  t1.OID,
  t1.PKID

左のテーブル ( table1 )のすべての行を、右のテーブルにペアがあるかどうかにかかわらず表示したい場合はLEFT JOIN、同じクエリを使用すると、目的の結果が得られます。

編集済み

この構造はパフォーマンスが高く、サブクエリを使用する必要はありません。

于 2013-01-30T22:51:37.340 に答える