ORACLE 仅在某些列中选择不同的值
Posted
技术标签:
【中文标题】ORACLE 仅在某些列中选择不同的值【英文标题】:ORACLE SELECT DISTINCT VALUE ONLY IN SOME COLUMNS 【发布时间】:2021-12-29 12:48:56 【问题描述】: +----+------+-------+---------+---------+
| 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 |
+----+------+-------+---------+---------+
我需要选择该表的所有字段,但每个 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);
【问题讨论】:
请从该输入中显示您需要的确切输出。 您希望每个id
和 type
有一行。 value
可以取自任何行。还有account
?您只需要帐户 1 吗?或者您实际上想要每个id
和type
和account
一行?或者你想像value
一样从行中获取任意account
?
每个 id 的帐户值始终相同(与值相关)。抱歉隐私,我可以分享真正的价值观,我用通用名称值创建了一个快速简单的例子
您不关心选择了哪一行,但每次运行查询时它是否需要是同一行(确定性)?您是否需要它是不确定的并且每次运行时能够返回不同的行?等等等等?
这能回答你的问题吗? Select First Row of Every Group in sql
【参考方案1】:
您似乎需要为每个不同的 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,type)随机排序;这意味着在这种情况下,通常很耗时的订购步骤将变得微不足道。此外,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 和类型对行进行分区,它不会对它们进行排序(这意味着随机排序),并且只从每个分区中选择“第一”行。请注意,包括row_number()
在内的一些分析函数需要order by
子句(即使我们不关心排序)-order by null
是习惯性的,但不能完全省略。相比之下,在match_recognize
中,您可以省略order by
子句(默认为“随机顺序”)。另一方面,您不能省略define
子句,即使它没有施加任何条件。为什么 Oracle 也不为该子句使用默认值,只有 Oracle 知道。
【讨论】:
有一个看似独特的列(命名为order
,只是为了与关键字发生冲突),然后可以使用它来使这个确定性,尽管仍然是任意的。跨度>
@MatBailie - 但是 OP 在他的尝试中明确使用了 ROWID,而不是这个 ORDER 列,这表明他不想重视 ORDER。
我相信那是投影。 OP 说I don't care the value of the type
,除此之外,其他一切都是假设。 OP可能想要确定性,可能不关心确定性,可能想要避免确定性;这完全是模棱两可的(order
的使用也是如此;不使用它并不表示不想使用它)。因此,我只是将其作为一个选项,而不是一个明确的要求。
我想说的是,我们需要从重复的寄存器中选择一个,不介意类型的值是否为 1,2,3... 只需要每个 id+type 组合中的一个。
在 19c 中他们还引入了any_value
聚合函数,该函数每组返回一个表达式值,这可能更具可读性(但组的随机属性是非常奇怪的要求)。由于“已优化返回第一个值”,因此检查性能会很有趣以上是关于ORACLE 仅在某些列中选择不同的值的主要内容,如果未能解决你的问题,请参考以下文章