1

次のような一時テーブル ( @TempPackages) があります。

EntryId (PK)    PackageId    SubProductID    SubProductSequence
1               1111         17              3
2               1111         28              4
3               1111         33              1
4               1111         67              5
5               1111         122             2
6               2222         18              4
7               2222         29              5
8               2222         33              9
9               2222         103             7
10              2222         99              11
11              3333         256             5
12              3333         333             6
13              3333         789             3
14              3333         1023            2
15              3333         9845            1

SubProductSequence各 uniqueの最小/最大値を持つ行を提供するクエリが必要ですPackageId。上記のテーブルの場合、クエリは次のように返します。

EntryId (PK)    PackageId    SubProductID    SubProductSequence
3               1111         33              1
4               1111         67              5
6               2222         18              4
10              2222         99              11
12              3333         333             6
15              3333         9845            1

このEntryId列は、同じテーブルを結合するための一意の列を提供するため、これを解決しようとして追加したものです (結合されたテーブルに 15 行しかないことを確認するため)。

私はこれを試しました-取得するためだけにMIN():

SELECT
    *
FROM
    @TempPackages p1
INNER JOIN
    @TempPackages p2 ON p1.EntryId = p2.EntryId
    AND p1.SubProductSequence = (
        SELECT
            MIN(SubProductSequence)
        FROM
            @DeparturesToUpdate)

パッケージごとの最小シーケンス番号ではなく、最小の全体シーケンス番号を持つ行を選択するため、節INNER JOINが不必要であり、句が間違っているため、明らかにこれは間違っています。SELECT MIN()

これを行うための最良の方法について何か提案はありますか?

4

3 に答える 3

4

1つの方法は、ROW_NUMBER()関数を使用することです。

SELECT
    EntryId 
  , PackageId 
  , SubProductID 
  , SubProductSequence
FROM
  ( SELECT
        EntryId 
      , PackageId 
      , SubProductID 
      , SubProductSequence
      , ROW_NUMBER() OVER (PARTITION BY PackageId
                           ORDER BY SubProductSequence ASC)
          AS rna
      , ROW_NUMBER() OVER (PARTITION BY PackageId
                           ORDER BY SubProductSequence DESC)
          AS rnd
    FROM
        @TempPackages
  ) AS tmp 
WHERE
      rna = 1
   OR rnd = 1 ;

ROW_NUMBER()OVER句とともに使用されるランキング関数です。この場合、基本的には、行を同じものでグループ化しPackageId(これは、で実行されますPARTITION BY PackageId)、行をSubProductSequence(昇順または降順で)並べ替えて、packageIdごとに1から始まるrow_numberを割り当てます。

したがって、サブクエリが単独で実行された場合、サブクエリはこれを返します。

EntryId (PK)    PackageId    SubProductID    SubProductSequence  rna  rnd
3               1111         33              1                    1    5
5               1111         122             2                    2    4
1               1111         17              3                    3    3
2               1111         28              4                    4    2
4               1111         67              5                    5    1

6               2222         18              4                    1    5
7               2222         29              5                    2    4
9               2222         103             7                    3    3
8               2222         33              9                    4    2
10              2222         99              11                   5    1

15              3333         9845            1                    1    5
14              3333         1023            2                    2    4
13              3333         789             3                    3    3
11              3333         256             5                    4    2    
12              3333         333             6                    5    1

WHERE外部クエリで追加された条件は、後で明らかです。

于 2012-12-27T23:24:40.343 に答える
1

ボヘミアンのアイデアを改良 -

;WITH MinMax AS
(SELECT  PackageId ,
    MIN(SubProductSequence) [Min],
    MAX(SubProductSequence) [Max]
FROM    @TempPackages
GROUP BY PackageId )

SELECT EntryId, SubProductSequence, TP.PackageId, SubProductID FROM @TempPkges TP
INNER JOIN MinMax MM ON TP.PackageId = MM.PackageId 
AND (SubProductSequence = MM.[Min] OR SubProductSequence = MM.[Max])

そして、独自の ORDER BY を追加できます

于 2012-12-27T23:28:56.207 に答える
0
 WITH  t1 AS
 (SELECT PackageId,MIN(SubProductSequence) minm,MAX(SubProductSequence) maxm  
 FROM    #@TempPackages
 GROUPBY  PackageId
 )
 SELECT  pk.EntryId, pk.PackageId,pk.SubProductID,  pk.SubProductSequence 
 FROM  #@TempPackages pk INNER JOIN t1 
 ON pk.PackageId = t1.PackageId
 WHERE pk.SubProductSequence = t1.minm  OR
       pk.SubProductSequence = t1.maxm
于 2012-12-28T05:22:35.907 に答える