Sql 如何根据其他列中存在的值选择行

Sql 如何根据其他列中存在的值选择行,sql,sql-server,Sql,Sql Server,我知道这个问题的标题可能很模糊,但我不知道该如何表达。我有下表: i_id option p_id ---- ------ ---- 1 A 4 1 B 8 1 C 6 2 B 3 2 C 5 3 A 7 3 B 3 4 E 11 如何根据每个唯一I_id的选项列的值选择一行:如果存在“C”,则选择该行,否则选择带有“B”的行,

我知道这个问题的标题可能很模糊,但我不知道该如何表达。我有下表:

i_id  option  p_id
----  ------  ----
1     A       4
1     B       8
1     C       6
2     B       3
2     C       5
3     A       7
3     B       3
4     E       11
如何根据每个唯一I_id的选项列的值选择一行:如果存在“C”,则选择该行,否则选择带有“B”的行,或者选择带有“a”的行,这样结果集为:

i_id  option  p_id
----  ------  ----
1     C       6
2     C       5
3     B       3

这将为您提供按C、B、A排序的值,同时删除任何没有这些值的i_id记录

WITH ranked AS
(
   SELECT i_id, [option], p_id
      , ROW_NUMBER() OVER (PARTITION BY i_id ORDER BY CASE [option]
                                                         WHEN 'C' THEN 1
                                                         WHEN 'B' THEN 2
                                                         WHEN 'A' THEN 3
                                                         ELSE 4
                                                      END) AS rowNumber
   FROM yourTable
   WHERE [option] IN ('A', 'B', 'C')
)
SELECT r.i_id, r.[option], r.p_id
FROM ranked AS r
WHERE r.rowNumber = 1

好吧,我建议,如果你能给每个字母分配一个数字分数,这样更好的字母会有更高的分数,这个问题会变得更容易。然后,您可以使用MAX为每个组查找该选项得分最高的行。由于‘A’<‘B’<‘C’,我们可以在这里作弊,并使用选项作为分数,因此:

SELECT t1.i_id, t1.option, t1.p_id
  FROM thetable t1
  INNER JOIN (SELECT t2.i_id, MAX(option)
                FROM thetable t2
              GROUP BY t2.i_id) AS maximums
        ON t1.i_id = maximums.i_id
 WHERE option != 'D'

这假设{i_id,option}是表的自然键,即没有两行具有这两列相同的值组合;或者,您对该对列具有唯一性约束。

这不适用于i_id=4的情况,其中[options]='E',OP不希望出现该情况。
WITH ranked AS
(
   SELECT i_id, [option], p_id
      , ROW_NUMBER() OVER (PARTITION BY i_id ORDER BY CASE [option]
                                                         WHEN 'C' THEN 1
                                                         WHEN 'B' THEN 2
                                                         WHEN 'A' THEN 3
                                                         ELSE 4
                                                      END) AS rowNumber
   FROM yourTable
   WHERE [option] IN ('A', 'B', 'C')
)
SELECT r.i_id, r.[option], r.p_id
FROM ranked AS r
WHERE r.rowNumber = 1
SELECT t1.i_id, t1.option, t1.p_id
  FROM thetable t1
  INNER JOIN (SELECT t2.i_id, MAX(option)
                FROM thetable t2
              GROUP BY t2.i_id) AS maximums
        ON t1.i_id = maximums.i_id
 WHERE option != 'D'