给定这样的结果集,按AccountId
排序:
| AccountId | Foo | Bar | ... |
| 7981 | x | 12 | ... |
| 7981 | y | 23 | ... |
| 7981 | z | 8 | ... |
| 7981 | q | 142 | ... |
| 64734 | x | 31 | ... |
| 64734 | q | 12 | ... |
我想选择第一AccountId
的所有行,无论AccountId
的实际值如何,也不管行数如何。 (换句话说,选择所有行,直到第一列中的值发生更改。
获取此结果集需要大量的联接和子句,因此使用group by
之类的东西和限制来获取子查询中的第一个AccountId
不是我正在寻找的解决方案类型。因为我将不得不复制大量代码。
我一直在试验... over (partition by AccountId)
函数。但它们似乎都对partition by
创建的分区内的值进行操作。
我设想的一个解决方案是一个函数,它将数字 1 分配给第一个分区中的所有行partition by AccountId
,将数字 2 分配给第二个分区中的所有行,依此类推。然后我可以添加where group = 1
.
如何在子查询中选择最小 AccountId,然后显示具有此 AccountId 的所有行?
代码如下所示:
SELECT *
FROM accounts
WHERE AccountId IN (
SELECT MIN(AccountId)
FROM accounts
)
编辑: 既然你说这是一个很长的查询,那么你可以通过使用 EXISTS 而不是 IN 运算符来让它更快一点:
SELECT *
FROM accounts accsMain
WHERE EXISTS(
SELECT MIN(AccountId)
FROM accounts accsSub
WHERE accsMain.AccountId = accsSub.AccountId
)
如果只想引用该表一次,则可以使用窗口函数:
select t.*
from (select t.*, min(accountid) over () as min_accountid
from t
) t
where min_accountid = accountid;
或rank()
:
select t.*
from (select t.*, row_number() over (order by accountid) as seqnum
from t
) t
where seqnum = 1;
如果t
是复杂的查询或视图,这将非常有用。
以下查询返回第一个 AccountId 以及该帐户的所有其他行数据。下面的查询比其他解决方案更优化。
更新:我使用了多个 CTE 来解决问题。在更新中,您的查询仅使用过一次。
with
[query_result]
as
(
select
AccountId ,
Foo ,
Bar
from
[Your_Table]
),
first_account
as
(
select
AccountId,
row_number() over(order by AccountId) as RowNum
from
[query_result]
)
select
r.AccountId ,
r.Foo ,
r.Bar
from
[query_result] as r
inner join
first_account as fa
on
r.AccountId = fa.AccountId
where
fa.RowNum = 1;
我不确定我是否理解你的情况。 您可以使用分析功能。
select * from (
select first_value(AccountId) over() my_first_AccountId, complex_query.*
from
( select AccountId ,... from t1,t2..,tn order by t1.x,t2.y,t3.z> ) complex_query
)
where my_first_AccountId = AccountId
工作示例
select * from (
select first_value(table_name) over() my_first_value, complex_query.*
from
( select * from user_tab_cols order by table_name ) complex_query
)
where my_first_value = table_name
避免重复代码的一种方法是使用WITH
子句
with complex_query AS
(
SELECT AccountId, foo, bar, ...
... complex stuff here
)
SELECT *
FROM complex_query
WHERE
AccountId = ( SELECT MIN(AccountId) FROM complex_query)
;
如果您更喜欢分析函数,则可以在不指定分区部分的情况下使用它们,如下所示
SELECT MIN(AccountId) OVER() AS minAccountId, AccountId ...
然后它们对整个结果集进行操作