Sql 分区后从每个组获取特定值
我有一张桌子-Sql 分区后从每个组获取特定值,sql,oracle,Sql,Oracle,我有一张桌子- ID | Type | Val0 | Val1 | Group | Creation_date 1 | A | V1 | Val1 | G1 | 24sep, 2011 2 | A | V1 | Val2 | G1 | 27oct, 2008 3 | A | V2 | Val3 | G2 | 19oct, 2003 4 | B | X1 | Xal1 | G3 | 15 dec, 2001 5 | B
ID | Type | Val0 | Val1 | Group | Creation_date
1 | A | V1 | Val1 | G1 | 24sep, 2011
2 | A | V1 | Val2 | G1 | 27oct, 2008
3 | A | V2 | Val3 | G2 | 19oct, 2003
4 | B | X1 | Xal1 | G3 | 15 dec, 2001
5 | B | X2 | Xal2 | G4 | 15 dec, 2000
6 | B | X2 | Xal3 | G4 | 15 dec, 1990
7 | C | X3 | Xal4 | G5 | 23Dec, 2001
我只想保留特定类型的最新值,并提取出旧值,但不属于与最新项关联的组。所以,对于上面的表,我希望这些项目被提取出来-Val3,Xal2,Xal3,我可以稍后删除它们
由于A的最新值为Val1,属于G1组,因此B的最新值为Xal1,C的最新值为Xal4
有谁能建议我如何使用SQL实现这一点吗?您可以使用行号:
您可以使用行号。无需汇总:
select t.*
from (select t.*,
row_number() over (partition by t.type order by creation_date desc) as seqnum
from t
) t
where seqnum = 1;
但是,您需要不在此组中的值。也就是说,您需要val1中的值,其中seqnum不是1。这将是:
select t.val1
from (select t.*, min(seqnum) over (partition by t.type, t.group) as min_seqnum -- DON'T USE group FOR COLUMN NAMES!
from (select t.*,
row_number() over (partition by t.type order by creation_date desc) as seqnum
from t
) t
) t
where min_seqnum <> 1;
请编辑您的问题并显示您想要的结果。IGroup是Oracle中的保留字,您不应该将其用作列名。如果您还有一行Type='a',其中Group='G2',但Val1='Val2',该怎么办?也就是说,G1组和G2组显示相同的值“Val2”?是选择以后删除,还是单独删除?或者,您的业务规则保证这种情况不会发生吗?嘿,Val1中的每个项目只能属于一个组。属于两个组的一个值永远不会出现在我的用例中。嘿,现在我有一个用例,相同的值可以出现在两个组中。如果这不是其他组中的最新项目,我想选择时间。有人能告诉我怎么做吗?如果val1与最近一行的组属于同一组G1,OP不想拾取val1。因此,例如,不应选择Val2。在您的查询中,没有对“组”列的任何引用,因此它不可能是正确的。不同的人可能有不同的向上投票和向下投票标准。我的反对意见是那些显然无法满足要求的解决方案。在这种情况下,我认为需求已经非常清楚地陈述了,而您的查询甚至没有在任何地方引用group列,因此看到它不起作用是很简单的。我用我的赞成票和反对票试图使这个论坛成为一个更有用的地方。这种解决方案,尤其是来自经验丰富的成员的解决方案,根本没有任何帮助。撇开这个问题的格式不好这一事实不谈,除非你在集中注意力的同时阅读问题,否则你不会理解OP真正想要什么。你也可以不提他昨天在另一个专栏上问了类似的问题,我自动地认为这是有关联的,并且有相同的逻辑。回答缺少实际解决方案的一小部分,不应该被否决,不应该被否决,但不应该被蔑视地否决。你有一个简单的解决方案-因为你的答案实际上没有解决OP的问题,正如我指出问题后你很容易同意的那样,你可以简单地删除你的答案!然而,从你的反应来看,我认为你很高兴人们对你的答案投赞成票,这显然是不正确的。哈,是的,请多给我8个名声!!请。我打算修复这个答案mor**.@Neha-如果您需要排除可能出现在两个组中的值,包括最新组和较旧组,此解决方案将不起作用。但是,您可以使用Gordon符号从原始表中选择t.val1或更可能的t.type,t.val1,其中min_seqnum=1,并将其用作子查询。例如,从您的表中选择t.type,t.val1减去[Gordon在这里的子查询,从…中选择t.type,t.val1,但最后一行更改为min_seqnum=1]。嘿..谢谢..这个解决方案对我有效..但是如果我想排除出现在两个组中的项目,最近的和较旧的,有更好的解决方案吗?我可以使用您提供的子查询选项,但这将使查询运行时间更长@娜哈。我能想到的所有方法都需要子查询或更复杂的东西。
select t.val1
from (select t.*, min(seqnum) over (partition by t.type, t.group) as min_seqnum -- DON'T USE group FOR COLUMN NAMES!
from (select t.*,
row_number() over (partition by t.type order by creation_date desc) as seqnum
from t
) t
) t
where min_seqnum <> 1;