简体   繁体   English

SQL 过滤与 COALESCE 或 window function

[英]SQL filtering with COALESCE or window function

I have a table with the following simplified data:我有一个包含以下简化数据的表格:

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

And I want a result set of:我想要一个结果集:

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

So if a given FK value has a Type A, don't give me any rows with B, C, or D. Or if the value has a Type B, then filter out C and D, etc. This feels like I need to apply a window function or coalesce, but I'm not sure how to do it.因此,如果给定的 FK 值具有 A 类,则不要给我任何带有 B、C 或 D 的行。或者如果该值具有 B 类,则过滤掉 C 和 D 等。这感觉我需要应用 window function 或合并,但我不知道该怎么做。

Use:利用:

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

...or using CTE (no performance difference): ...或使用 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

Proof:证明:

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

Result:结果:

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

So, for each FK value, you want the minimal PK value that matches, and the corresponding type for the PK?那么,对于每个 FK 值,您想要匹配的最小 PK 值,以及 PK 的相应类型吗? As ever, do it in steps.与以往一样,分步进行。

Which are the PK values we want?我们想要的 PK 值是什么?

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

How to get the corresponding rows - why, join with the main table, of course:如何获取对应的行——为什么,加入主表,当然:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM