2017-04-06 84 views
0

我有麻烦试图找到然而,随着条件选择记录适当的查询(SQL-SERVER)一列重复的行,我将使用表中有超过10万行和20多个栏目。消除除非条件

所以,我需要满足以下条件的代码:

1)如果[政策]和[计划]列是行之间唯一的话,我会选择记录

2)如果[政策]和[计划]返回2行或多行,然后我将选择“代码”列不是999

3)在某些情况下不需要的行可能没有“999”在[代码]栏记录也可以是其他细节

换句话说,我想获得的行编号1,2,4,5,7。

这里的表是什么样子

row #|policy|plan|code 
----------------------- 
    1 | a | aa |111 
----------------------- 
    2 | b | bb |112 
----------------------- 
    3 | b | bb |999 
----------------------- 
    4 | c | cc |111 
----------------------- 
    5 | c | cc |112 
----------------------- 
    6 | c | cc |999 
----------------------- 
    7 | d | dd |999 
----------------------- 

我期待看到类似

row #|policy|plan|code 
----------------------- 
    1 | a | aa |111 
----------------------- 
    2 | b | bb |112 
----------------------- 
    4 | c | cc |111 
----------------------- 
    5 | c | cc |112 
----------------------- 
    7 | d | dd |999 
----------------------- 

预先感谢您

+1

请出示预期输出............... – Chanukya

+1

什么是你的努力?你有什么尝试过呢? –

回答

1

可能是你想要这个(消除了最后一排,如果不止一个)?

select t.* 
from (select t.* 
      , row_number() over (partition by policy, plan 
          order by code desc 
         ) AS RN 
      , COUNT(*) over (partition by policy, plan) AS RC 
     from t 
    ) t 
where RN > 1 OR RN=RC; 

输出:

row policy plan code RN RC 
1 1 a aa 111 1 1 
2 2 b bb 112 2 2 
3 5 c cc 112 2 3 
4 4 c cc 111 3 3 
5 7 d dd 999 1 1 
+0

@winery我用'plan'为你写的,但它是可能的,你应该使用'[计划]'在MSSQL – etsa

+0

谢谢您的方法,这就是我想要的东西。也感谢提及[计划]。 – winery

+0

你应该标记解决你的问题的答案。 – etsa

4

这听起来像一个优先查询的例子。您的使用row_number()

select t.* 
from (select t.*, 
      row_number() over (partition by policy, plan 
           order by code 
           ) as seqnum 
     from t 
    ) t 
where seqnum = 1; 

预期的输出使这更清楚一点:

select t.* 
from (select t.*, 
      rank() over (partition by policy, plan 
          order by (case when code = 999 then 1 else 2 end) desc 
         ) as seqnum 
     from t 
    ) t 
where seqnum = 1; 

的OP希望不在999除非唯一代码是999所有代码。因此,另一种方法是:

select t.* 
from t 
where t.code <> 999 
union all 
select t.* 
from t 
where t.code = 999 and 
     not exists (select 1 
        from t t2 
        where t2.policy = t.policy and t2.plan = t.plan and 
         t2.code <> 999 
       ); 
+0

谢谢你的回答,但如果不想要的行不总是999,但取决于条件,并且不能优先考虑,我该如何做到这一点。 – winery

+0

@winery。 。 。此问题指定999是“不需要的”行。如果还有其他问题,应该作为另一个问题提出。但是,在'by by'命令的'case'中放置一个条件来实现其他逻辑是很容易的。 –

+0

好吧,我想我明白了。谢谢你这么多的帮助 – winery

0
CREATE TABLE #Table2 
    ([row] int, [policy] varchar(1), [plan] varchar(2), [code] int) 
; 

INSERT INTO #Table2 
    ([row], [policy], [plan], [code]) 
VALUES 
    (1, 'a', 'aa', 111), 
    (2, 'b', 'bb', 112), 
    (3, 'b', 'bb', 999), 
    (4, 'c', 'cc', 111), 
    (5, 'c', 'cc', 112), 
    (6, 'c', 'cc', 999), 
    (7, 'd', 'dd', 999) 
; 
with cte 
as 
(
select *, 
row_number() over (partition by policy, [plan] 
           order by code 
           ) as seqnum 
     from #Table2 
) 

    select [row], [policy], [plan], [code] from cte where seqnum=1 
+0

谢谢您的回答 – winery

+0

对不起,我已经试过,但它说:“通过投票与铸造用不到15信誉记录,但是不改变公开展示后得分。”我认为那是因为我只是一个新用户。 – winery