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

一种方法是使用该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(升序或降序)对它们进行排序并分配一个 row_number,从每个 packageId 的 1 开始。

因此,如果子查询单独运行,它将返回:

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 回答