SQL find min&数据集中的最大范围

时间:2010-12-28 17:58:42

标签: sql sql-server

我有一个包含以下列的表:

contactId  (int)  
interval   (int)  
date (smalldate)  

小样本数据:

1,120,'12/02/2010'  
1,121,'12/02/2010'  
1,122,'12/02/2010'  
1,123,'12/02/2010'  
1,145,'12/02/2010'  
1,146,'12/02/2010'  
1,147,'12/02/2010'  
2,122,'12/02/2010'  
2,123,'12/02/2010'  
2,124,'12/02/2010'  
2,320,'12/02/2010'  
2,321,'12/02/2010'  
2,322,'12/02/2010'  
2,450,'12/02/2010'  
2,451,'12/02/2010'  

如何/可能 - 让sql返回列“contactId,minInterval,maxInterval,date”,例如

1,120,123,'12/02/2010'  
1,145,147,'12/02/2010'  
2,122,124,'12/02/2010'  
2,320,322,'12/02/2010'  
2,450,451,'12/02/2010'  

希望这是有道理的,基本上我想找出提供者和时间间隔的最小/最大间隔范围。它们增加1的范围的日期...一旦间隔增量器中断(例如多于一个),则表示新的最小/最大范围......

非常感谢任何帮助:)

这是我确切的SQL表设置:

create table availability  
(  
 Id  (int)  
 ProviderId (int)  
 IntervalId (int)  
 Date (date)  
)  

示例数据

providerid,intervalid,date  
1128,108,2010-12-27  
1128,109,2010-12-27  
1128,110,2010-12-27  
1128,111,2010-12-27  
1128,112,2010-12-27  
1128,113,2010-12-27  
1128,114,2010-12-27  
1128,120,2010-12-27  
1128,121,2010-12-27  
1128,122,2010-12-27  
1128,123,2010-12-27  
1128,124,2010-12-27  
1128,125,2010-12-27  
1213,108,2010-12-27  
1213,109,2010-12-27  
1213,110,2010-12-27  
1213,111,2010-12-27  
1213,112,2010-12-27  
1213,113,2010-12-27  
1213,114,2010-12-27  
1213,115,2010-12-27  
1213,232,2010-12-27  
1213,233,2010-12-27  
1213,234,2010-12-27  
3954,198,2010-12-27  
3954,199,2010-12-27  
3954,200,2010-12-27  
3954,201,2010-12-27   
3954,202,2010-12-27  
3954,203,2010-12-27   
3954,204,2010-12-27  
3954,205,2010-12-27  
3954,206,2010-12-27  
3954,207,2010-12-27  
3954,208,2010-12-27  
3954,209,2010-12-27  
3954,210,2010-12-27  
3954,211,2010-12-27  
3954,212,2010-12-27  
3954,213,2010-12-27  
3954,214,2010-12-27  
3954,215,2010-12-27  
3954,216,2010-12-27  
3954,217,2010-12-27  
3954,218,2010-12-27  
3954,229,2010-12-27  
3954,230,2010-12-27  
3954,231,2010-12-27  
3954,232,2010-12-27  
3954,233,2010-12-27  
3954,234,2010-12-27  
1128,108,2010-12-28  
1128,109,2010-12-28  
1128,110,2010-12-28  
1128,111,2010-12-28  
1128,112,2010-12-28  
1128,113,2010-12-28  
1128,114,2010-12-28  
1128,115,2010-12-28  
1128,116,2010-12-28  
3954,186,2010-12-28  
3954,187,2010-12-28  
3954,188,2010-12-28  
3954,189,2010-12-28  
3954,190,2010-12-28  
3954,213,2010-12-28  
3954,214,2010-12-28  
3954,215,2010-12-28  
3954,216,2010-12-28  
3954,217,2010-12-28  
3954,218,2010-12-28  
3954,219,2010-12-28  
3954,220,2010-12-28  
3954,221,2010-12-28  
3954,222,2010-12-28  

在答案中使用当前sql的示例结果:

1062,180,180,2010-12-20  
1062,179,179,2010-12-20  
1062,178,178,2010-12-20  
1062,177,177,2010-12-20  
1062,176,176,2010-12-20  
1062,175,175,2010-12-20  
1062,174,174,2010-12-20  
1062,173,173,2010-12-20  
1062,172,172,2010-12-20  
1062,171,171,2010-12-20  
1062,170,170,2010-12-20  
1062,169,169,2010-12-20    
1062,168,168,2010-12-20  
1062,167,167,2010-12-20  
1062,166,166,2010-12-20  
1062,165,165,2010-12-20  
1062,164,164,2010-12-20  
1062,163,163,2010-12-20  
1062,162,162,2010-12-20  
1062,161,161,2010-12-20  
1062,160,160,2010-12-20  
1062,159,159,2010-12-20  
1062,158,158,2010-12-20  
1062,157,157,2010-12-20  
1062,156,156,2010-12-20  
1062,155,155,2010-12-20  
1062,154,154,2010-12-20  
1062,153,153,2010-12-20  
1062,152,152,2010-12-20  
1062,151,151,2010-12-20  
1062,150,150,2010-12-20  
1062,149,149,2010-12-20  
1062,148,148,2010-12-20  
1062,147,147,2010-12-20  
1062,146,146,2010-12-20  
1062,145,145,2010-12-20  
1062,144,144,2010-12-20  
1062,143,143,2010-12-20  
1062,142,142,2010-12-20  
1062,141,141,2010-12-20  
1062,140,140,2010-12-20  
1062,139,139,2010-12-20  
1062,138,138,2010-12-20  
1062,137,137,2010-12-20  
1062,136,136,2010-12-20  
1062,135,135,2010-12-20  
1062,134,134,2010-12-20  
1062,133,133,2010-12-20  
1062,132,132,2010-12-20  
1062,131,131,2010-12-20  
1062,130,130,2010-12-20  
1062,129,129,2010-12-20  
1062,128,128,2010-12-20  
1062,127,127,2010-12-20  
1062,126,126,2010-12-20  
1062,125,125,2010-12-20  
1062,124,124,2010-12-20  
1062,123,123,2010-12-20  
1062,122,122,2010-12-20  
1062,121,121,2010-12-20  
1062,120,120,2010-12-20  
1062,119,119,2010-12-20  
1062,118,118,2010-12-20  
1062,117,117,2010-12-20  
1062,116,116,2010-12-20  
1062,115,115,2010-12-20  
1062,114,114,2010-12-20  
1062,113,113,2010-12-20  
1062,112,112,2010-12-20  

2 个答案:

答案 0 :(得分:5)

SQL ServerOraclePostgreSQL

WITH    q AS
        (
        SELECT  t.*, interval - ROW_NUMBER() OVER (PARTITION BY contactID, date ORDER BY interval) AS sr
        FROM    mytable t
        )
SELECT  contactID, date, MIN(interval), MAX(interval)
FROM    q
GROUP BY
        date, contactID, sr
ORDER BY
        date, contactID, sr

<强>更新

使用您的测试数据,我得到了这个输出:

WITH    mytable (providerId, intervalId, date) AS
        (
        SELECT  1128,108,'2010-12-27' UNION ALL
        SELECT  1128,109,'2010-12-27' UNION ALL
        SELECT  1128,110,'2010-12-27' UNION ALL
        SELECT  1128,111,'2010-12-27' UNION ALL
        SELECT  1128,112,'2010-12-27' UNION ALL
        SELECT  1128,113,'2010-12-27' UNION ALL
        SELECT  1128,114,'2010-12-27' UNION ALL
        SELECT  1128,120,'2010-12-27' UNION ALL
        SELECT  1128,121,'2010-12-27' UNION ALL
        SELECT  1128,122,'2010-12-27' UNION ALL
        SELECT  1128,123,'2010-12-27' UNION ALL
        SELECT  1128,124,'2010-12-27' UNION ALL
        SELECT  1128,125,'2010-12-27'
        ),
        q AS
        (
        SELECT  t.*, intervalId - ROW_NUMBER() OVER (PARTITION BY providerId, date ORDER BY intervalId) AS sr
        FROM    mytable t
        )
SELECT  providerId, date, MIN(intervalId), MAX(intervalId)
FROM    q
GROUP BY
        date, providerId, sr
ORDER BY
        date, providerId, sr

1128  2010-12-27  108  114
1128  2010-12-27  120  125

,我。即正是你所追求的。

您确定正确使用了查询吗?你在(providerId, intervalId, date)上有重复吗?

答案 1 :(得分:0)

单独使用SQL查询可能会做到这一点,但它可能有点令人难以置信。基本上是一个子查询,用于查找增加1的位置,与原始数据集连接,其中包含大量其他逻辑。这至少是我的印象。

如果我是你,

如果这是一次性交易,请不要关心性能,只是迭代它并“手动”进行计算。

如果这是一个生产数据集,您需要在频繁/自动/性能密集型设置上执行此操作,则重新排列原始数据集以使这种查询更容易。

希望您可以使用其中一个选项。