简体   繁体   English

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    |
    +----+------+-------+---------+---------+

I need get a select of all fields of this table but only getting 1 row for each combination of id+type (I don't care the value of the type).我需要获得该表所有字段的 select 但对于 id+type 的每个组合只能获得 1 行(我不在乎类型的值)。 But I tried some approach without result.但我尝试了一些没有结果的方法。

At the moment that I make an DISTINCT I cant include rest of the fields to make it available in a subquery.在我进行 DISTINCT 的那一刻,我不能包含字段的 rest 以使其在子查询中可用。 If I add ROWNUM in the subquery all rows will be different making this not working.如果我在子查询中添加 ROWNUM ,所有行都会不同,这会导致它不起作用。

Some ideas?一些想法?

My better query at the moment is this:我目前更好的查询是:

SELECT ID, TYPE, VALUE, ACCOUNT
FROM MYTABLE
WHERE ROWID IN (SELECT DISTINCT MAX(ROWID)    
                FROM MYTABLE
                GROUP BY ID, TYPE);

It seems you need to select one (random) row for each distinct combination of id and type.似乎您需要为每个不同的 id 和类型组合 select 一个(随机)行。 If so, you could do that efficiently using the row_number analytic function.如果是这样,您可以使用row_number分析 function 有效地做到这一点。 Something like this:像这样的东西:

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 means random ordering of rows within each group (partition) by (id, type); order by null表示每组(分区)内的行按(id,type)随机排序; this means that the ordering step, which is usually time-consuming, will be trivial in this case.这意味着在这种情况下,通常很耗时的订购步骤将变得微不足道。 Also, Oracle optimizes such queries (for the filter rn = 1 ).此外,Oracle 优化了此类查询(对于过滤器rn = 1 )。

Or, in versions 12.1 and higher, you can get the same with the match_recognize clause:或者,在 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
);

This partitions the rows by id and type, it doesn't order them (which means random ordering), and selects just the "first" row from each partition.这将按 id 和类型对行进行分区,它不对它们进行排序(这意味着随机排序),并且只从每个分区中选择“第一”行。 Note that some analytic functions, including row_number() , require an order by clause (even when we don't care about the ordering) - order by null is customary, but it can't be left out completely.请注意,一些分析函数,包括row_number() ,需要order by子句(即使我们不关心排序) - order by null是习惯性的,但不能完全省略。 By contrast, in match_recognize you can leave out the order by clause (the default is "random order").相比之下,在match_recognize中,您可以省略order by子句(默认为“随机顺序”)。 On the other hand, you can't leave out the define clause, even if it imposes no conditions whatsoever.另一方面,您不能省略define子句,即使它没有施加任何条件。 Why Oracle doesn't use a default for that clause too, only Oracle knows.为什么 Oracle 也不使用该子句的默认值,只有 Oracle 知道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM