如何在Firebird中使用DISTINCT ON(PostgreSQL)?

Fox*_*Tâm 5 sql firebird distinct distinct-on

我有一个带有数据的TempTable:

------------------------------------
| KEY_1 | KEY 2 | NAME   | VALUE   |
------------------------------------
|     1 |  0001 | NAME 2 | VALUE 1 |
|     1 |  0002 | NAME 1 | VALUE 3 |
|     1 |  0003 | NAME 3 | VALUE 2 |
|     2 |  0001 | NAME 1 | VALUE 2 |
|     2 |  0001 | NAME 2 | VALUE 1 |
------------------------------------
Run Code Online (Sandbox Code Playgroud)

我想获得以下数据:

------------------------------------
| KEY_1 | KEY 2 | NAME   | VALUE   |
------------------------------------
|     1 |  0001 | NAME 2 | VALUE 1 |
|     2 |  0001 | NAME 1 | VALUE 2 |
------------------------------------
Run Code Online (Sandbox Code Playgroud)

在PostgreSQL中,我使用查询DISTINCT ON:

SELECT DISTINCT ON (KEY_1) KEY_1, KEY_2, NAME, VALUE
FROM TempTable
ORDER BY KEY_1, KEY_2
Run Code Online (Sandbox Code Playgroud)

在Firebird中,如何获取上述数据的数据?

Gor*_*off 6

Firebird 3.0支持窗口功能,因此您可以使用:

select . . .
from (select t.*,
             row_number() over (partition by key_1 order by key_2) as seqnum
      from temptable t
     ) t
where seqnum = 1;
Run Code Online (Sandbox Code Playgroud)

在早期版本中,您可以使用多种方法.这是一个相关的子查询:

select t.*
from temptable t
where t.key_2 = (select max(t2.key_2)
                 from temptable t2
                 where t2.key_1 = t.key_1
                );
Run Code Online (Sandbox Code Playgroud)

注意:key_1由于重复项,这仍将返回重复值key_2.唉...除非每行都有唯一的标识符,否则只获取一行很棘手.


Tho*_*ner 6

DISTINCT ON考虑到该ORDER BY子句,PostgreSQL 采用每个声明的组密钥的第一行.在其他DBMS(包括Firebird的更高版本)中,您可以使用ROW_NUMBER它.您按所需顺序对每个组键的行编号,并保留编号为#1的行.

select key_1, key_2, name, value
from
(
  select key_1, key_2, name, value,
    row_number() over (partition by key_1 order by key_2) as rn
  from temptable
) numbered
where rn = 1
order by key_1, key_2;
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您有一个平局(key_1 = 2/key_2 = 0001两次出现),DBMS任意选择其中一行.(你必须扩展sortkey DISTINCT ON以及ROW_NUMBER决定选择哪一个.)如果你想要两行,即显示所有绑定的行,你可以使用RANK(或DENSE_RANK)代替ROW_NUMBER,这DISTINCT ON是不可能的.