我可以将下面的GroupBy子句修改为更好的一个

时间:2017-01-10 17:52:51

标签: sql sql-server

考虑以下案例

CASE 1:  tbl_a
---------------
| colA | colB |
---------------      expected O/P:   1  0 
|  1   |  0   |
---------------

CASE 2:  tbl_a
---------------
| colA | colB |
---------------      expected O/P:   1  1
|  1   |  1   |
---------------

CASE 3:  tbl_a
---------------
| colA | colB |
---------------     expected O/P:   1  1
|  1   |  0   |
|  1   |  1   |
---------------

CASE 4:  tbl_a
---------------
| colA | colB |
---------------     expected O/P:  NULL NULL
| null | null |
---------------

查询很简单,如果有记录,其中colA = 1且colB = 1则返回它,如果不存在此类记录,则返回colA = 1的现有记录。 我尝试了各种方法。我带了groupBy子句,但有一种简单的方法可以做到。

如果我使用ColA = 1且colB = 1,那么对于案例1,它会失败,它不返回任何行。

 SELECT colA, Max(colb) group by (colA) 

这是有效查询吗?非常感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

请尝试以下方法。它为发布的案例提供了所需的结果。

SELECT TOP 1 colA, colB 
  FROM tbl_a 
 WHERE colA = 1 OR colA IS NULL
 ORDER BY colA DESC, colB DESC;

答案 1 :(得分:0)

我认为您编写的查询很适合数据,但不适用于您描述的一般情况。

尝试使用以下脚本并使用@scenario变量的值来查看它为不同数据返回的数据。

使用/调整表结构的最后一个查询。

declare @tbl table (colA int, colB int)
declare @scenario char(1) = 'D'

if @scenario = 'A'
    insert @tbl values (1, 0)
else if @scenario = 'B'
    insert @tbl values (1, 1)
else if @scenario = 'C'
    insert @tbl values (1, 0), (1, 1)
else if @scenario = 'D'
    insert @tbl values (null, null)

select *
    from @tbl
    where (colA = 1 and colB = 1)
        or (colA = 1 and not exists (select 1 from @tbl where colA = 1 and colB = 1))
        or (colA is null and colB is null and not exists (select 1 from @tbl where colA = 1 and colB = 1))

您还可以在每个方案中使用“更多随机数据”测试查询,如下所示:

declare @tbl table (colA int, colB int)
declare @scenario char(1) = 'B'

if @scenario = 'A'
    insert @tbl values (1, 0), (0, 1), (0, 0), (0, null)
else if @scenario = 'B'
    insert @tbl values (1, 1), (1, 0), (null, null)
else if @scenario = 'C'
    insert @tbl values (1, 0), (1, 1), (0, 0), (1, 0), (null, 0)
else if @scenario = 'D'
    insert @tbl values (null, null)

select *
    from @tbl
    where (colA = 1 and colB = 1)
        or (colA = 1 and not exists (select 1 from @tbl where colA = 1 and colB = 1))
        or (colA is null and colB is null and not exists (select 1 from @tbl where colA = 1 and colB = 1))

答案 2 :(得分:0)

使用row_number基于您的优先级排序并使用最小行号作为结果的行的不同方法。

select colA,colB
from (select x.*,min(rn) over() as minrn 
      from (select t.*
            ,row_number() over(order by case when colA=1 and colB=1 then 1
                                             when colA=1 then 2
                                        else 3 end) as rn
             from t 
            ) x
     ) y 
where rn=minrn