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

9

我将执行两个表之间的连接操作,并添加一个条件,希望仅获取满足连接条件和“extern”条件的第一行。

例如,此查询:

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

首先,我想知道如何使用个人资料(v.profile或p.id)将此内部连接的结果分组。然后如何仅显示每个组的第一个出现。

提前感谢。


你能展示一些样本数据和期望结果吗?并且你需要定义什么使得特定的行成为“第一个”匹配。 - Alex Poole
1
你说的 "extern" 条件是什么意思?你考虑过使用 and ROWNUM=1参见 Oracle 文档)吗?补充说明:这将为您提供仅 1 个匹配结果,但在查询中可能不一致。另请参阅 ROWID - wmorrison365
"extern"条件是一种不同于连接条件的条件。连接条件不是显式的,而是在where子句中需要一些条件。 - Jorge Vega Sánchez
5个回答

12

您可以使用分析查询来完成此操作:

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提供一行。

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


1
@JorgeVegaSánchez - 你的 profileuser 表是否有相同名称的列?如果是,你需要显式地列出它们,而不是使用 *,并为重复的列取别名,以便它们看起来具有不同的名称(假设你确实想检索两个表的数据)。 - Alex Poole
没有列名相同的情况。我可以毫不费力地进行连接:选择* 从prmprofile p 加入用户v,其中v.profil = p.id 其中p.langue = 0 和v.userid像'%TEST%'; - Jorge Vega Sánchez
1
@JorgeVegaSánchez - 如果有重复,连接仍然可以工作,但是我使用的外部select如果它们都有一个名为name的列(例如或者其中一个有rn),就会出现错误。请在问题中添加表定义。 - Alex Poole
抱歉,两个表中有相同名称的列。是否有一种简单的选项可以“打印”除一个之外的所有列?但这解决了您发布的查询。谢谢。 - Jorge Vega Sánchez
@JorgeVegaSánchez - 不好意思,你需要逐个列出它们。 - Alex Poole

3

请尝试以下方法:

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;

但不对生成的连接表进行分组,以仅显示每个组的第一次出现。 - Jorge Vega Sánchez
“group”列是哪一列? - TechDo

1
你可以使用 LIMIT 关键字。
select * from PRMPROFILE p, user v
where 
p.id = v.profile
and p.language = 0
and v.userid like '%TEST%'
limit 1

3
在12c版本之前,Oracle不支持LIMIT语句。此外,这也无法解决问题中提到的“分组”部分;原帖作者希望每个profile ID只有一行结果,而不是整个查询只有一行结果。 - Alex Poole

1
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

2
请编辑您的答案以使用代码块格式。另外,请包含您答案的解释。 - mypetlion

0

它将仅显示顶部结果

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

4
Oracle有这个语法吗? - Thilo
对不起,我把它给了 SQL。 - user1613212

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接