如何仅选择满足条件的第一行?

Posted

技术标签:

【中文标题】如何仅选择满足条件的第一行?【英文标题】: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 子句中需要一些条件。 【参考方案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 - 您当然可以将其更改为更合适的东西,这样会在重新运行查询。 (您可以查看rankdense_rank 以了解选择“第一”行的替代方法)。

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

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

【讨论】:

@JorgeVegaSánchez - 你的profileuser 表有同名的列吗?如果是这样,您需要明确列出它们而不是使用*,并为重复项设置别名,以便它们看起来具有不同的名称(假设您实际上想要检索两者)。 没有同名的列。我可以毫无问题地进行加入: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

以上是关于如何仅选择满足条件的第一行?的主要内容,如果未能解决你的问题,请参考以下文章

如何更有效地从n组中找到满足给定条件的最小组合?

PySpark 窗口函数标记满足特定条件的每个分区的第一行

仅选择必须满足两个条件的记录

从满足条件A的组中选择行。如果不是,请给我一行满足条件B的行

SQL:如果两个条件都满足而不是在多个where中单独排除,如何仅排除条件?

mysql 条件满足就抓一行,不满足就抓另一个