如何仅选择满足条件的第一行?
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 - 您当然可以将其更改为更合适的东西,这样会在重新运行查询。 (您可以查看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以上是关于如何仅选择满足条件的第一行?的主要内容,如果未能解决你的问题,请参考以下文章
从满足条件A的组中选择行。如果不是,请给我一行满足条件B的行