2013-07-09 16 views
0

我有一个源数据集是这样的(简化为更清楚):通过顺序依赖分区进行聚合?

Key F1 F2 
1 X 4 
2 X 5 
3 Y 6 
4 X 9 
5 X 7 
6 X 8 
7 Y 9 
8 X 6 
9 X 5 
10 Y 3 

的数据由所述密钥字段排序。现在,我想计算F1字段定义的分区上F2字段的聚合:分区从第一个X值开始,以第一个后续Y值结束。因此,例如,我可能希望在如上所述定义的分区上计算MIN()。那么结果集是这样的:

rownum MIN(F2) 
1  4 
2  7 
3  3 

我已经尝试了大量的资源,但什么也没发现我的情况(包括我们自己的内部网的社区,当然还有计算器)。通常,分区只适用于可用于标识分区的字段。在这里,分区是通过相对于给定顺序的字段内容的变化来定义的。

尽管我知道我可能不得不诉诸编写程序性解决方案,但我宁愿在纯SQL中解决此问题。

任何想法如何使用SQL select语句实现这样的分区?

感谢和问候 启。

+0

使用PARTITION BY和GROUPING查看[OVER](http://msdn.microsoft.com/en-us/library/ms189461%28v=sql.105%29.aspx)子句。我现在无法访问SQL-Server,所以无法测试任何代码,但它应该是这样的: \t select min(f2)over(partition by f1)as [minval] \t group by f1 – pasty

+0

@如果您没有可用的sql引擎,则为pasty。给sqlfiddle一个镜头:http://sqlfiddle.com/ –

+0

@DavidSöderlund谢谢,我会马上尝试! – pasty

回答

1

一点点短溶液:http://sqlfiddle.com/#!12/7390d/24

查询:

select min(f2) 
from t t1 
group by (select max(key) 
      from t t2 
      where t2.f1='Y' and 
       t1.key > t2.key) 

结果:

| MIN | 
------- 
| 4 | 
| 7 | 
| 3 | 

的想法是找到前述的键' Y'为每一行都由它组成。应该与任何SQL引擎一起工作。

+0

谢谢,Stas S - 就是这样对我! –

0

没有指定引擎或方言或版本,所以我认为SQL Server 2012的

的例子,你可以看到运行的解决方案:http://sqlfiddle.com/#!6/f5d38/21

您在您所设定的创建正确的分区解决问题。代码看起来像这样。

WITH groupLimits as 
(
SELECT 
[Key] AS groupend 
,COALESCE(LAG([Key]) OVER (order by [Key]),0)+1 AS groupstart 
FROM sourceData 
WHERE F1 = 'Y' 
) 
SELECT 
MIN(sourceData.F2) 
FROM groupLimits 
INNER JOIN sourceData 
    ON sourceData.[Key] BETWEEN groupLimits.groupstart and groupLimits.groupend 
GROUP BY groupLimits.groupstart 
ORDER BY groupLimits.groupstart 
+0

谢谢大卫,指向sqlfiddle! –