使用COALESCE或窗口函数进行SQL过滤

时间:2011-07-07 22:00:50

标签: sql sql-server tsql

我有一张包含以下简化数据的表格:

PK    FK   Type
----------------
1     11    A
2     11    B
3     12    B
4     13    C
5     13    D
6     14    D

我想要一个结果集:

PK    FK   Type
---------------
1     11    A
3     12    B
4     13    C
6     14    D

因此,如果给定的FK值具有类型A,请不要给我任何带有B,C或D的行。或者如果该值具有类型B,则过滤掉C和D等。这感觉就像我需要应用窗口函数或合并,但我不知道该怎么做。

2 个答案:

答案 0 :(得分:4)

使用:

SELECT x.* 
  FROM (SELECT s.*, 
               ROW_NUMBER() OVER(PARTITION BY s.fk
                                     ORDER BY s.pk) rnk
          FROM YOUR_TABLE s) x
 WHERE x.rnk = 1

...或使用CTE(无性能差异):

WITH example AS (
  SELECT s.*, 
         ROW_NUMBER() OVER(PARTITION BY s.fk
                               ORDER BY s.pk) rnk
    FROM sample s)
SELECT x.* 
  FROM example x
 WHERE x.rnk = 1

证明:

WITH sample AS (
  SELECT 1 AS PK, 11 AS FK, 'A' AS [TYPE]
  UNION ALL
  SELECT 2 AS PK, 11 AS FK, 'B' AS [TYPE]
  UNION ALL
  SELECT 3 AS PK, 12 AS FK, 'B' AS [TYPE]
  UNION ALL
  SELECT 4 AS PK, 13 AS FK, 'C' AS [TYPE]
  UNION ALL
  SELECT 5 AS PK, 13 AS FK, 'D' AS [TYPE]
  UNION ALL
  SELECT 6 AS PK, 14 AS FK, 'D' AS [TYPE])
SELECT x.* 
  FROM (SELECT s.*, ROW_NUMBER() OVER(PARTITION BY s.fk
                                          ORDER BY s.pk) rnk
          FROM sample s) x
 WHERE x.rnk = 1

结果:

pk   fk   type
----------------
1    11   A
3    12   B
4    13   C
6    14   D

答案 1 :(得分:1)

那么,对于每个FK值,您需要匹配的最小PK值以及PK的相应类型吗?和往常一样,分步进行。

我们想要的PK值是什么?

SELECT FK, MIN(PK) AS PK
  FROM SimplifiedData
 GROUP BY FK

如何获取相应的行 - 为什么,加入主表,当然:

SELECT S.PK, S.FK, S.Type
  FROM SimplifiedData AS S
  JOIN (SELECT FK, MIN(PK) AS PK
          FROM SimplifiedData
         GROUP BY FK
       ) AS T ON S.PK = T.PK
 ORDER BY S.FK;