sql—选择列的最小非重复值的行的查询

nqwrtyyt  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(255)

我需要为a列的每一行选择列b最小值的行,但它应该不同于迄今为止为a列选择的其他值。所以a的顺序很重要。另外,如果b用完了,没有留下任何值,那么a的后面的值应该为null或者不出现在结果中。
a和b都是数字(或时间戳)。例子:

A   | B | 
----+---+
1   | 3 | 
1   | 5 | 
1   | 6 | 
2   | 3 | 
2   | 5 | 
9   | 3 |
9   | 5 |

因此期望的结果是:

A   | B | 
----+---+
1   | 3 | 
2   | 5 |
``` `select A, min(B) group by A` 显然不起作用,因为我不想b被重复。 `Distinct` 也不起作用,因为行已经不同了。我在任何地方都找不到类似的问题。我使用的实际数据是红移时间序列的数据库,所以a和b是时间戳。cte将受到特别欢迎。
ehxuflar

ehxuflar1#

首先我认为这可以通过 ROW_NUMBER () OVER (ORDER PARTITION BY B DESC) 但是有一个问题,b中的数字不应该重复。
目前唯一想到的是做临时table,我知道这不是最好的方法,但你可能可以改进它

DECLARE @Tabla1 TABLE(A INT) 
DECLARE @Tabla2 TABLE(B INT)
DECLARE @Tabla3 TABLE(A INT, B INT)
INSERT INTO @Tabla1 SELECT DISTINCT A FROM PRUEBA

WHILE (SELECT COUNT(*) FROM @Tabla1) > 0
BEGIN
  DECLARE @A INT, @B INT;
  SET @A = (SELECT TOP 1  * FROM @Tabla1);
  SET @B = (SELECT MIN(B) FROM PRUEBA WHERE A = @A AND B NOT IN(SELECT * FROM @Tabla2));
  INSERT INTO @Tabla2 VALUES (@B)
  DELETE FROM @Tabla1 WHERE A = @A
  INSERT INTO @Tabla3 SELECT A, B FROM PRUEBA WHERE A = @A AND B = @B
END

SELECT * FROM @Tabla3

也许您可以使用游标,但是您必须计算出需要更多计算开销的游标或临时表

gg0vcinb

gg0vcinb2#

这基本上是一个“寻找对角线”的问题。你需要知道a中b的秩和a的秩。我相信这适用于给定的数据:

select A, B from (
  select row_number() over (partition by A order by B) as RN,
    dense_rank() over (order by A) as DR.
    A, B
    from <table> )
where RN = DR;

对于更复杂的情况,此解决方案将变得更复杂。
附录:因为我知道会有人问这个问题,这是一个有趣的问题,所以我想出了这样一个更复杂的解决方案:

select min(A) as A, B from (
  select decode(A <> nvl(min(A) over (order by DRB, DRA rows between unbounded preceding and 1 preceding),-1), true, 'good', 'no good') as Y,
    A, B from (
    select dense_rank() over (partition by B order by A) as DRA,
      dense_rank() over ( order by B) as DRB,
      A, B from <table>
  )
  where DRA <= DRB
)
where Y = 'good'
group by B
order by A, B;

相关问题