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

问题描述 投票:1回答:1

有一个简单的场景,其中,一个表存储有关用户使用哪些卡以及这些卡是否已在系统中注册(存在)的数据。我也应用了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,对于用户C,将返回CardID = 8
  2. 否则,如果系统中没有用户存在(注册)的卡,则只取第一张。因此,对于用户B,它应该返回CardID = 4

因此,最终返回的集应该是-

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

如何在SQL中执行此过滤?

谢谢

sql tsql row-number
1个回答
2
投票

您可以使用:

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;

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

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
© www.soinside.com 2019 - 2024. All rights reserved.