按首选排序

时间:2016-12-13 01:05:13

标签: 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

如果一个成员有一个AI想要返回所有带有该成员A的行。
如果一个成员没有A,那么我想返回所有含有该成员B的行。

我意识到我可以使用NOT EXISTS编写解决方案,但我想知道是否有更通用的解决方案(如果是多个类别)。基本上我想按照首选顺序过滤类别是否存在。

在此示例中,结果将返回:

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

感谢。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

你可以试试这个:

     ;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
Member      ID          Type HasA
----------- ----------- ---- -----------
100         1           A    1
101         3           A    1
102         4           A    1
103         5           B    0
104         7           A    1
104         8           A    1