ORACLE SELECT 仅在某些列中有不同的值
ORACLE SELECT DISTINCT VALUE ONLY IN SOME COLUMNS
+----+------+-------+---------+---------+
| id | order| value | type | account |
+----+------+-------+---------+---------+
| 1 | 1 | a | 2 | 1 |
| 1 | 2 | b | 1 | 1 |
| 1 | 3 | c | 4 | 1 |
| 1 | 4 | d | 2 | 1 |
| 1 | 5 | e | 1 | 1 |
| 1 | 5 | f | 6 | 1 |
| 2 | 6 | g | 1 | 1 |
+----+------+-------+---------+---------+
我需要获取此 table 的所有字段的 select,但对于 id+type 的每个组合只获取 1 行(我不关心类型的值)。但是我尝试了一些方法没有结果。
在我制作 DISTINCT 的那一刻,我无法包含其余字段以使其在子查询中可用。如果我在子查询中添加 ROWNUM,所有行都会不同,这将无法正常工作。
一些想法?
我目前更好的查询是:
SELECT ID, TYPE, VALUE, ACCOUNT
FROM MYTABLE
WHERE ROWID IN (SELECT DISTINCT MAX(ROWID)
FROM MYTABLE
GROUP BY ID, TYPE);
您似乎需要 select 为每个不同的 ID 和类型组合创建一个(随机)行。如果是这样,您可以使用 row_number
分析函数有效地做到这一点。像这样:
select id, type, value, account
from (
select id, type, value, account,
row_number() over (partition by id, type order by null) as rn
from your_table
)
where rn = 1
;
order by null
表示每个组(分区)内的行按(id,类型)随机排序;这意味着通常很耗时的排序步骤在这种情况下将变得微不足道。此外,Oracle 优化了此类查询(针对过滤器 rn = 1
)。
或者,在 12.1 及更高版本中,您可以使用 match_recognize
子句获得相同的结果:
select id, type, value, account
from my_table
match_recognize (
partition by id, type
all rows per match
pattern (^r)
define r as null is null
);
这按 id 和类型对行进行分区,它不对它们进行排序(这意味着随机排序),select只是每个分区的“第一”行。请注意,一些分析函数,包括 row_number()
,需要一个 order by
子句(即使我们不关心顺序)- order by null
是习惯的,但不能省略完全地。相反,在 match_recognize
中,您可以省略 order by
子句(默认为“随机顺序”)。另一方面,您不能省略 define
子句,即使它没有施加任何条件。为什么 Oracle 也不为该子句使用默认值,只有 Oracle 知道。
+----+------+-------+---------+---------+
| id | order| value | type | account |
+----+------+-------+---------+---------+
| 1 | 1 | a | 2 | 1 |
| 1 | 2 | b | 1 | 1 |
| 1 | 3 | c | 4 | 1 |
| 1 | 4 | d | 2 | 1 |
| 1 | 5 | e | 1 | 1 |
| 1 | 5 | f | 6 | 1 |
| 2 | 6 | g | 1 | 1 |
+----+------+-------+---------+---------+
我需要获取此 table 的所有字段的 select,但对于 id+type 的每个组合只获取 1 行(我不关心类型的值)。但是我尝试了一些方法没有结果。
在我制作 DISTINCT 的那一刻,我无法包含其余字段以使其在子查询中可用。如果我在子查询中添加 ROWNUM,所有行都会不同,这将无法正常工作。
一些想法?
我目前更好的查询是:
SELECT ID, TYPE, VALUE, ACCOUNT
FROM MYTABLE
WHERE ROWID IN (SELECT DISTINCT MAX(ROWID)
FROM MYTABLE
GROUP BY ID, TYPE);
您似乎需要 select 为每个不同的 ID 和类型组合创建一个(随机)行。如果是这样,您可以使用 row_number
分析函数有效地做到这一点。像这样:
select id, type, value, account
from (
select id, type, value, account,
row_number() over (partition by id, type order by null) as rn
from your_table
)
where rn = 1
;
order by null
表示每个组(分区)内的行按(id,类型)随机排序;这意味着通常很耗时的排序步骤在这种情况下将变得微不足道。此外,Oracle 优化了此类查询(针对过滤器 rn = 1
)。
或者,在 12.1 及更高版本中,您可以使用 match_recognize
子句获得相同的结果:
select id, type, value, account
from my_table
match_recognize (
partition by id, type
all rows per match
pattern (^r)
define r as null is null
);
这按 id 和类型对行进行分区,它不对它们进行排序(这意味着随机排序),select只是每个分区的“第一”行。请注意,一些分析函数,包括 row_number()
,需要一个 order by
子句(即使我们不关心顺序)- order by null
是习惯的,但不能省略完全地。相反,在 match_recognize
中,您可以省略 order by
子句(默认为“随机顺序”)。另一方面,您不能省略 define
子句,即使它没有施加任何条件。为什么 Oracle 也不为该子句使用默认值,只有 Oracle 知道。