简体   繁体   English

如何基于其他列中值的存在选择行

[英]How to select row based on existance of value in other column

I realise the title to this question may be vague but I am not sure how to phrase it. 我知道这个问题的标题可能含糊不清,但我不确定该如何措辞。 I have the following table: 我有下表:

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

How do I select a row based on the value of the option column for each unique i_id : if 'C' exists, select the row, else select row with 'B' else with 'A' so that result set is: 如何基于每个唯一i_idoption列的值选择一行:如果存在'C' ,请选择该行,否则选择带有'B'的行,否则选择'A'这样结果集是:

i_id  option  p_id
----  ------  ----
1     C       6
2     C       5
3     B       3
select i_id, option, p_id
from (
  select
    i_id,
    option,
    p_id,
    row_number() over (partition by i_id order by case option when 'C' then 0 when 'B' then 1 when 'A' then 2 end) takeme
  from thetable
  where option in ('A', 'B', 'C')
) foo
where takeme = 1

This will give you the values ordered by C, B, A, while removing any i_id record that does not have one of these values. 这将为您提供按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
create table t2 (
  id int,
  options varchar(1),
  pid int
)

insert into t2 values(1, 'A', 4)
insert into t2 values(1, 'B', 8)
insert into t2 values(1, 'C', 6)
insert into t2 values(1, 'E', 7)

select t2.* from t2,
(select id, MAX(options) as op from t2
 where options <> 'E'
 group by id) t
where t2.id = t.id   and t2.options = t.op

Well, I would suggest that this problem can be made easier if you can assign a numeric "score" to each letter, such that "better" letters have higher scores. 好吧,我建议您可以为每个字母分配一个数字“分数”,使“更好”的字母得分更高,从而使此问题变得更容易。 Then you can use MAX to find, for each group, the row with the highest "score" for the option. 然后,您可以使用MAX为每个组查找选项具有最高“分数”的行。 Since 'A' < 'B' < 'C', we could cheat here and use option as the score, and thus: 由于'A'<'B'<'C',我们可以在这里作弊并使用option作为得分,因此:

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'

This assumes that {i_id, option} is a natural key of the table (ie, that no two rows will have the same combination of values for those two columns; or, alternatively, that you have an uniqueness constraint on that pair of columns). 假设{i_id, option}是表的自然键(即,没有两行具有相同的值组合,这两列的值;或者对这对列具有唯一性约束) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM