SQL获取按一列区分但又按另一列区分的另一列的行

时间:2019-10-02 17:42:59

标签: sql distinct

我有以下数据集:

enter image description here

这是交叉连接的输出,该交叉连接使用函数将左侧的每个值与右侧的每个值进行比较,但这并不重要。

我需要从中得到两行,在这种情况下,我需要第一行和第四行。

逻辑是...我希望在b_index列上具有最高的累加值,而不是从已经使用过的a列的行中区分出来。

所以..第一行必须是b_index = 1的地方,b_index的最大累加值为95,并且所有a_index值都可用,所以我想要该行。这将使a_index 2无法用于下一行

第二个b_index为2,查找所有可用的a_index值,在这种情况下,我只有a_index 1可用,并且我想要具有最高累加值的行。

我已经使用stackoverflow很久了,但这是我的第一篇文章,所以如果我做错了,请保持友善:)

请提前感谢您

更新:

CREATE TABLE #example
  ( 
    a_index int,
    b_index int,
    a varchar(max),
    b varchar(max),
    accu int
  ) 


INSERT INTO #example (a_index, b_index, a, b, accu)
    VALUES
        (3,1,'dddd','dddd',95),
        (1,1,'aaaa','dddd',0),
        (2,1,'bbbb','dddd',0),
        (1,2,'aaaa','aaaa',95),
        (3,2,'dddd','aaaa',0),
        (2,2,'bbbb','aaaa',0),
        (1,3,'aaaa','aaaa',95),
        (3,3,'dddd','aaaa',0),
        (2,3,'bbbb','aaaa',0)
b_index 1 should match a_index 3 because it has the highest accu
b_index 2 should match a_index 1 because it has the highest accu and was not previously used
b_index 3 should match a_index 2 because it is the only one left unused

它也可以以其他方式工作,但是列表已预先排序,以便从b_index列开始更容易

a_index 1 -> b_index 3
a_index 3 -> b_index 1 (because a_index 3 has a higher max accu then 2)
a_index 2 -> b_index 2 

您可以忽略列a和b,它们无关紧要

2 个答案:

答案 0 :(得分:0)

您需要类似以下相关子查询的内容来检查每次a是否存在于其他父组中

  Select Max(aindex), 
        bindex,max(a) , b, 
     max(accunit) 
     From (Select a.index, *  from table 
      where bindex, b in (Select 1,2 from(  
        Select bindex
       , b, 
     max(accunit)
    From table group by bindex, 
     b)
        )) t group 
      by bindex, b having 
    1=max( Case when aindex <> 
          t.aindex then 1
       Else 0 end) ;

答案 1 :(得分:0)

我可能会继续尝试寻找递归CTE解决方案(我对rCTE还是陌生的)。但是,我认为此CURSOR解决方案将起作用:

declare @example table
  ( 
    a_index int,
    b_index int,
    a varchar(max),
    b varchar(max),
    accu int
  ) 

INSERT INTO @example (a_index, b_index, a, b, accu)
    VALUES
        (3,1,'dddd','dddd',95),
        (1,1,'aaaa','dddd',0),
        (2,1,'bbbb','dddd',0),
        (1,2,'aaaa','aaaa',95),
        (3,2,'dddd','aaaa',0),
        (2,2,'bbbb','aaaa',0),
        (1,3,'aaaa','aaaa',95),
        (3,3,'dddd','aaaa',0),
        (2,3,'bbbb','aaaa',0)

declare @output table (a_index int, b_index int)
declare @b_index int

declare out_cursor cursor
for
    select distinct b_index
    from @example
    order by b_index
;

open out_cursor

fetch next from out_cursor into @b_index

while @@fetch_status = 0
    begin
        insert into @output
        select min(a_index) a_index, a.b_index
        from (
            select b_index, max(accu) accu
            from @example
            where b_index = @b_index
                and a_index not in (select a_index from @output)
            group by b_index
        ) a
        inner join @example e
            on a.b_index=e.b_index
            and a.accu=e.accu
            and a_index not in (select a_index from @output)
        group by a.b_index

        fetch next from out_cursor into @b_index
    end

close out_cursor
deallocate out_cursor

select *
from @output