Sql 按首选排序筛选列表

Sql 按首选排序筛选列表,sql,sql-server,Sql,Sql Server,这可能有一个显而易见的解决方案,但我不记得现在该怎么称呼它 假设你有一张这样的桌子: Member | ID | Type ------ | ------ | ------ 100 | 1 | A 100 | 2 | B 101 | 3 | A 102 | 4 | A 103 | 5 | B 104 | 6 | B 104 | 7 | A 104 | 8 | A

这可能有一个显而易见的解决方案,但我不记得现在该怎么称呼它

假设你有一张这样的桌子:

Member | ID     | Type
------ | ------ | ------
100    | 1      | A
100    | 2      | B
101    | 3      | A
102    | 4      | A
103    | 5      | B
104    | 6      | B
104    | 7      | A
104    | 8      | A
如果成员有a,我希望返回该成员的所有行和a。
如果成员没有a,则我希望返回该成员的所有行和B

我意识到我可以使用notexists编写一个解决方案,但我想知道是否有更通用的解决方案(在多个类别的情况下)。基本上,我想根据类别是否存在进行筛选,以首选顺序进行筛选

在本例中,结果将返回:

Member | ID     | Type
------ | ------ | ------
100    | 1      | A
101    | 3      | A
102    | 4      | A
103    | 5      | B
104    | 7      | A
104    | 8      | A
谢谢

Declare @YourTable table (Member int,ID int,[Type] varchar(25))
Insert Into @YourTable values
(100 , 1 , 'A'),
(100 , 2 , 'B'),
(101 , 3 , 'A'),
(102 , 4 , 'A'),
(103 , 5 , 'B'),
(104 , 6 , 'B'),
(104 , 7 , 'A'),
(104 , 8 , 'A')

Select Member,ID,Type
 From (
         Select *
               ,RN = Dense_Rank() over (Partition By Member Order by Type)
          From  @YourTable
      ) A
 Where RN=1 
返回

Member  ID  Type
100     1   A
101     3   A
102     4   A
103     5   B
104     7   A
104     8   A
返回

Member  ID  Type
100     1   A
101     3   A
102     4   A
103     5   B
104     7   A
104     8   A
你能试试这个吗

     ;WITH tb(Member,ID ,Type)AS
     (
        SELECT  100,1,'A' UNION
        SELECT  100,2,'B' UNION
        SELECT  101,3,'A' UNION
        SELECT  102,4,'A' UNION
        SELECT  103,5,'B' UNION
        SELECT  104,6,'B' UNION
        SELECT  104,7,'A' UNION
        SELECT  104,8,'A'
    )
    SELECT * FROM (
        SELECT *,MAX(CASE WHEN type='A' THEN 1 ELSE 0 END )OVER(PARTITION BY tb.Member) HasA  FROM tb
     ) AS t WHERE (t.HasA=1 AND t.Type='A') OR t.HasA=0
成员ID类型HasA ----------- ----------- ---- ----------- 100 1 A 1 101 3 A 1 102 4 A 1 1035B0 104 7 A 1 104 8 A 1 你能试试这个吗

     ;WITH tb(Member,ID ,Type)AS
     (
        SELECT  100,1,'A' UNION
        SELECT  100,2,'B' UNION
        SELECT  101,3,'A' UNION
        SELECT  102,4,'A' UNION
        SELECT  103,5,'B' UNION
        SELECT  104,6,'B' UNION
        SELECT  104,7,'A' UNION
        SELECT  104,8,'A'
    )
    SELECT * FROM (
        SELECT *,MAX(CASE WHEN type='A' THEN 1 ELSE 0 END )OVER(PARTITION BY tb.Member) HasA  FROM tb
     ) AS t WHERE (t.HasA=1 AND t.Type='A') OR t.HasA=0
成员ID类型HasA ----------- ----------- ---- ----------- 100 1 A 1 101 3 A 1 102 4 A 1 1035B0 104 7 A 1 104 8 A 1
是的,行得通。但我看不出这将如何适用于有十几个类别的情况。我怎样才能把它变成一个更通用的解决方案?你能提供更多关于你需求的细节吗?是的,这很有效。但我看不出这将如何适用于有十几个类别的情况。我怎样才能把它变成一个更通用的解决方案呢?你能提供更多关于你的需求的细节吗?这似乎很管用。我以前没听说过稠密的等级。谢谢大家!@窗口函数是我们的朋友。花时间去适应它们是值得的。干杯。这似乎很管用。我以前没听说过稠密的等级。谢谢大家!@窗口函数是我们的朋友。花时间去适应它们是值得的。干杯