TSQL - 从一组行中获取第一个匹配项

TSQL - Picking up first match from a group of rows

我有一个简单的场景,其中 table 存储有关用户使用哪些卡以及这些卡是否在系统中注册(存在)的数据。我也应用 ROW_NUMBER 将它们分组

SELECT User, CardId, CardExists, ROW_NUMBER() OVER (PARTITION BY User) AS RowNum From dbo.CardsInfo

User   | CardID | CardExists | RowNum
-------------------------------------
A      | 1      |   0        |  1
A      | 2      |   1        |  2
A      | 3      |   1        |  3
---------------------------------
B      | 4      |   0        |  1
B      | 5      |   0        |  2
B      | 6      |   0        |  3
B      | 7      |   0        |  4
---------------------------------
C      | 8      |   1        |  1
C      | 9      |   0        |  2
C      | 10     |   1        |  3

现在在上面,我需要根据下面的两个规则过滤掉用户名片

  1. 如果一个用户注册的卡中,系统中存在多张卡,取第一张。因此,对于用户 A,CardID 2 将被 returned 而对于用户 C,它将 return CardID = 8
  2. 否则,如果系统中没有(注册)该用户的卡,则只取第一张。所以,对于用户B,应该return CardID = 4

因此,最终的 returned 集应该是 -

User   | CardID | CardExists | RowNum
-------------------------------------
A      | 2      |   1        |  2
---------------------------------
B      | 4      |   0        |  1
---------------------------------
C      | 8      |   1        |  1

如何在 SQL 中进行过滤?

谢谢

您可以使用:

SELECT ci.*
FROM (SELECT User, CardId, CardExists,
             ROW_NUMBER() OVER (PARTITION BY User ORDER BY CardExists DESC, CardId) AS RowNum
      FROM dbo.CardsInfo ci
     ) ci
WHERE seqnum = 1;

您也可以通过聚合来做到这一点:

select user,
       max(cardexists) as cardexists,
       coalesce(min(case when cardexists = 1 then cardid end),
                min(card(cardid)
               ) as cardid
from cardsinfo
group by user;

或者,如果您有单独的用户 table:

select ci.*
from users u cross apply
     (select top (1) ci.*
      from cardinfo ci
      where ci.user = u.user
      order by ci.cardexists desc, cardid asc
     ) ci