如何在 Firebird 中使用 DISTINCT ON(PostgreSQL 的)?
How to use DISTINCT ON (of PostgreSQL) in Firebird?
我有一个包含数据的临时表:
------------------------------------
| 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 |
------------------------------------
我要获取以下数据:
------------------------------------
| KEY_1 | KEY 2 | NAME | VALUE |
------------------------------------
| 1 | 0001 | NAME 2 | VALUE 1 |
| 2 | 0001 | NAME 1 | VALUE 2 |
------------------------------------
在 PostgreSQL 中,我使用 DISTINCT ON
:
的查询
SELECT DISTINCT ON (KEY_1) KEY_1, KEY_2, NAME, VALUE
FROM TempTable
ORDER BY KEY_1, KEY_2
在Firebird中,如何获取上述数据?
Firebird 3.0 支持window个函数,所以你可以使用:
select . . .
from (select t.*,
row_number() over (partition by key_1 order by key_2) as seqnum
from temptable t
) t
where seqnum = 1;
在早期版本中,您可以使用多种方法。这是一个相关的子查询:
select t.*
from temptable t
where t.key_2 = (select max(t2.key_2)
from temptable t2
where t2.key_1 = t.key_1
);
注意:由于 key_2
的重复值,key_1
的值仍然 return 重复。唉。 . .除非每一行都有一个唯一的标识符,否则只得到一行是很棘手的。
PostgreSQL 的 DISTINCT ON
考虑到 ORDER BY
子句,每个规定的组键取第一行。在其他 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;
在您的示例中,您有一个平局(key_1 = 2 / key_2 = 0001 出现两次)并且 DBMS 任意选择其中一行。 (你必须在 DISTINCT ON
和 ROW_NUMBER
中扩展排序键来决定选择哪一个。)如果你想要两行,即显示所有绑定的行,你会使用 RANK
(或 DENSE_RANK
)而不是 ROW_NUMBER
,这是 DISTINCT ON
无法做到的。
我有一个包含数据的临时表:
------------------------------------
| 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 |
------------------------------------
我要获取以下数据:
------------------------------------
| KEY_1 | KEY 2 | NAME | VALUE |
------------------------------------
| 1 | 0001 | NAME 2 | VALUE 1 |
| 2 | 0001 | NAME 1 | VALUE 2 |
------------------------------------
在 PostgreSQL 中,我使用 DISTINCT ON
:
SELECT DISTINCT ON (KEY_1) KEY_1, KEY_2, NAME, VALUE
FROM TempTable
ORDER BY KEY_1, KEY_2
在Firebird中,如何获取上述数据?
Firebird 3.0 支持window个函数,所以你可以使用:
select . . .
from (select t.*,
row_number() over (partition by key_1 order by key_2) as seqnum
from temptable t
) t
where seqnum = 1;
在早期版本中,您可以使用多种方法。这是一个相关的子查询:
select t.*
from temptable t
where t.key_2 = (select max(t2.key_2)
from temptable t2
where t2.key_1 = t.key_1
);
注意:由于 key_2
的重复值,key_1
的值仍然 return 重复。唉。 . .除非每一行都有一个唯一的标识符,否则只得到一行是很棘手的。
PostgreSQL 的 DISTINCT ON
考虑到 ORDER BY
子句,每个规定的组键取第一行。在其他 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;
在您的示例中,您有一个平局(key_1 = 2 / key_2 = 0001 出现两次)并且 DBMS 任意选择其中一行。 (你必须在 DISTINCT ON
和 ROW_NUMBER
中扩展排序键来决定选择哪一个。)如果你想要两行,即显示所有绑定的行,你会使用 RANK
(或 DENSE_RANK
)而不是 ROW_NUMBER
,这是 DISTINCT ON
无法做到的。