如何根据多列的值选择行并比较结果集中这些列的值?

时间:2016-09-04 09:16:11

标签: sql sql-server tsql

我有一张表格如下:

A|  B|  C|  D|
1   3   1   25/2/2016
2   4   2   25/4/2016
2   5   1   22/2/2016
3   5   1   23/2/2016
3   5   1   23/6/2016

现在我希望结果集具有以下条件:

  • B值为3或4的所有行。
  • 仅当A的值为唯一时,才将包含值B的行包含为5 为它。

例如在上表中,对于B的值为5的行,A的值为2,并且已经存在值为A为2的行,其中B的值为4,则不包括该行。

  • 但是B的值为5,A的值为3的行 包括因为没有A的值为3的行和B的值 是3或4。
  • 另外,有2个这样的行,其中A的值是3,B是5,所以我 想要选择具有最新值D的那个。

所需的输出表:

A|  B|  C|  D|
1   3   1   25/2/2016
2   4   2   25/4/2016
3   5   1   23/6/2016

3 个答案:

答案 0 :(得分:1)

使用OUTER APPLY的另一种方法:

SELECT DISTINCT b34.*
FROM YourTable y
OUTER APPLY (
    SELECT TOP 1    *
    FROM YourTable
    WHERE y.A = A AND B IN (3,4,5)
    ORDER BY B,D DESC
    ) b34

输出:

A   B   C   D
1   3   1   2016-02-25
2   4   2   2016-04-25
3   5   1   2016-06-23

答案 1 :(得分:0)

您可以为B = 5的唯一A创建子查询/ CTE。并将其与您的数据结合起来。

with unqA as (
   select A,max(D) D 
   from data 
   group by A
   having max(B)=5 and min(B)=5)
select d.A,d.B,d.C,d.D
from data d
   left join unqA  u on (d.B=5 and d.A = u.A and d.D  = u.D)
where d.B in (3,4) or u.A is not null

答案 2 :(得分:0)

这是优先级查询。我会使用rank()中的逻辑使用order by处理此问题:

select t.*
from (select t.*,
             rank() over (partition by a
                          order by (case when b in (3, 4) then 1 else 2 end),
                                   (case when b not in (3, 4) then d end) desc
                         ) as seqnum
      from t
     ) t
where seqnum = 1;

这是order by使用两个键。当b为3或4时,则第一个键为1,第二个键为NULL - 返回所有此类行。当某些东西不是3或4时,只返回最新的东西。

您的问题表明,a的给定值可能有3/4的多行,这将返回所有行。