【问题标题】:How to select only first rows that satisfies conditions?如何仅选择满足条件的第一行?
【发布时间】:2013-04-08 16:36:00
【问题描述】:

我正在两个表之间进行连接并添加一个条件,希望只获得满足连接条件和“外部”条件的第一行。

这个查询例如:

select * from PRMPROFILE p, user v
where 
p.id = v.profile
and p.language = 0
and v.userid like '%TEST%';

首先,我想知道如何使用配置文件(v.profile 或 p.id)对这个内部连接的结果进行分组。之后如何只显示每个组的第一次出现。

提前致谢。

【问题讨论】:

  • 您能展示一些示例数据和预期结果吗?并且您需要定义使特定行成为“第一”匹配的原因。
  • “外部”条件是什么意思?您是否考虑过使用and ROWNUM=1(see Oracle docs)?附录:这只会为您提供 1 个匹配结果,但在查询之间可能不一致。另请参阅ROWID。
  • “extern”条件是与加入条件不同的条件。连接不是显式的,它在 where 子句中需要一些条件。

标签: sql oracle select join group-by


【解决方案1】:

您可以为此使用分析查询:

select *
from (
    select p.*, v.*,
        row_number() over (partition by p.id order by v.userid) as rn
    from prmprofile p
    join user v on v.profile = p.id
    where p.language = 0
    and v.userid like '%TEST%'
)
where rn = 1;

内部查询获取所有数据(但使用* 并不理想),并添加一个额外的列,为每个p.id 值分配一个行号序列。它们必须按某些东西排序,而且您还没有说是什么使特定行成为“第一”,所以我猜想是用户 ID - 您当然可以将其更改为更合适的东西,这样会在重新运行查询。 (您可以查看rank 和dense_rank 以了解选择“第一”行的替代方法)。

外部查询仅将结果集限制为额外列具有值1 的结果集,这将为每个p.id 提供一行。

另一种方法是使用子查询来识别“第一”行并加入该行,但尚不清楚标准是什么以及它是否具有足够的选择性。

【讨论】:

  • @JorgeVegaSánchez - 你的profile 和user 表有同名的列吗?如果是这样,您需要明确列出它们而不是使用*,并为重复项设置别名,以便它们看起来具有不同的名称(假设您实际上想要检索两者)。
  • 没有同名的列。我可以毫无问题地进行加入:select * from prmprofile p join user v on v.profil = p.id where p.langue = 0 and v.userid like '%TEST%';
  • @JorgeVegaSánchez - 连接仍然适用于重复项,但我使用的外部 select 如果他们都有一个名为 name 的列,例如(或者一个有rn)。请将表格定义添加到问题中。
  • 抱歉,两个表中都有同名的列。是否有任何简单的选项可以“打印”除一列之外的所有列?但这解决了您发布的查询。谢谢。
  • @JorgeVegaSánchez - 不,恐怕不是,您需要单独列出它们。
【解决方案2】:

请尝试:

select * from(
  select *, 
    row_number() over (partition by v.userid order by v.userid) RNum
  from PRMPROFILE p, user v
  where 
  p.id = v.profile
  and p.language = 0
  and v.userid like '%TEST%'
  )x 
where RNum=1;

【讨论】:

  • 但不会对生成的连接表进行分组以仅显示每个组的第一次出现。
  • group 列是哪个?
【解决方案3】:

您可以使用 LIMIT 关键字。

select * from PRMPROFILE p, user v
where 
p.id = v.profile
and p.language = 0
and v.userid like '%TEST%'
limit 1

【讨论】:

  • Oracle 没有LIMIT(显然,直到 12c)。它也不会解决问题的“分组”部分; OP 希望每个配置文件 ID 有一行,而不是整个查询的一行。
【解决方案4】:
select * from PRMPROFILE p, user v
where p.id = v.profile and p.language = 0
and v.userid like '%TEST%'
fetch first 1 row only

【讨论】:

  • 请编辑您的答案以使用代码块格式。还请附上您的答案的解释。
【解决方案5】:

它只会显示最上面的结果

select top 1 * from PRMPROFILE p, user v
where 
    p.id = v.profile
    and p.language = 0
    and v.userid like '%TEST%';

【讨论】:

  • Oracle 有这种语法吗?
  • 对不起。我给它的 sql
猜你喜欢
  • 2015-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 2014-02-18
  • 2017-07-06
  • 2019-04-24
  • 1970-01-01
相关资源
最近更新 更多