2011-12-20 81 views
2

我意识到这个问题的标题可能含糊不清,但我不知道如何对其进行定义。我有以下表格:如何根据其他列中值的存在来选择行

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 

如何选择基础上,option列的每个独特i_id的值的行:如果'C'存在,选择该行,否则选择行与'A'使'B'其他结果集为:

​​

回答

2
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 
+0

非常感谢GSerg。所有的答案非常感谢。 – 2011-12-21 13:57:50

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 
+0

这对于i_id = 4的情况不适用,其中[options] ='E',OP不希望显示出来。 – 2011-12-20 18:43:34

+0

谢谢,我解决了它。 – demas 2011-12-20 18:46:51

2

这会给你的C,B,A下令值,而删除ny 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 
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}是表(即一个自然的关键,没有两行将为这两列具有相同的值组合;或者,您对该列对具有唯一性约束)。