SQL 获取一列不同但另一列不同的行,按第三列排序
SQL Get rows distinct by one column but also distinct on another column ordered by third column
我有如下一组数据:
这是交叉联接的输出,它使用函数比较左侧的每个值和右侧的每个值,但这有点不相关。
我需要从中得到两行,在这种特殊情况下我想要第一行和第四行。
逻辑是...我想在具有最高 accu 值的 b_index 列上进行区分,而不是在已经使用过的 a 列行中进行区分。
所以.. 第一行必须是 b_index = 1,b_index 的最大 accu 是 95 并且所有 a_index 值都可用所以我想要那一行。这使得 a_index 2 无法用于下一行
第二个 b_index 是 2,寻找所有可用的 a_index 值,在这种情况下我只有 a_index 1 可用,我想要具有最高精确度的行。
我已经使用 Whosebug 很长时间了,但这是我的拳头 post 所以如果我做错了请多多包涵 :)
提前感谢您的帮助
更新:
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 列,它们无关紧要
你需要像下面的相关子查询这样的东西来检查每次 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) ;
我可能会继续尝试寻找递归 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
我有如下一组数据:
这是交叉联接的输出,它使用函数比较左侧的每个值和右侧的每个值,但这有点不相关。
我需要从中得到两行,在这种特殊情况下我想要第一行和第四行。
逻辑是...我想在具有最高 accu 值的 b_index 列上进行区分,而不是在已经使用过的 a 列行中进行区分。
所以.. 第一行必须是 b_index = 1,b_index 的最大 accu 是 95 并且所有 a_index 值都可用所以我想要那一行。这使得 a_index 2 无法用于下一行
第二个 b_index 是 2,寻找所有可用的 a_index 值,在这种情况下我只有 a_index 1 可用,我想要具有最高精确度的行。
我已经使用 Whosebug 很长时间了,但这是我的拳头 post 所以如果我做错了请多多包涵 :)
提前感谢您的帮助
更新:
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 列,它们无关紧要
你需要像下面的相关子查询这样的东西来检查每次 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) ;
我可能会继续尝试寻找递归 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