SQL 组范围值

发布于 2024-11-14 18:58:33 字数 667 浏览 3 评论 0原文

我已经查看了这里的其他几个问题/答案,但我无法将它们应用于我的问题。我试图根据关键列识别多个连续中断。我发现的大多数示例都不会处理同一键列的序列中的多个中断。

Sample data:
Location     Number
------------------------
300          15
300          16
300          17
300          18
300          21
300          22
300          23
400          10
400          11
400          14
400          16

Here is the result I am looking for:
Location     StartNumber    StartNumber
------------------------------------------
300                   15             18
300                   21             23
400                   10             11
400                   14             14
400                   16             16

I have taken a look at several other questions/answers on here but I cannot apply those to my problem. I am trying to identify multiple sequential breaks based on a key column. Most examples I have found do not deal with multiple breaks in a sequence for the same key column.

Sample data:
Location     Number
------------------------
300          15
300          16
300          17
300          18
300          21
300          22
300          23
400          10
400          11
400          14
400          16

Here is the result I am looking for:
Location     StartNumber    StartNumber
------------------------------------------
300                   15             18
300                   21             23
400                   10             11
400                   14             14
400                   16             16

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

坏尐絯 2024-11-21 18:58:33

这是相对可移植的 SQL 解决方案,因为您没有指定数据库

Create Table  SampleData  (Location int, Number Int)
INSERT INTO SampleData VALUES (300, 15)
INSERT INTO SampleData VALUES (300, 16)
INSERT INTO SampleData VALUES (300, 17)
INSERT INTO SampleData VALUES (300, 18)
INSERT INTO SampleData VALUES (300, 21)
INSERT INTO SampleData VALUES (300, 22)
INSERT INTO SampleData VALUES (300, 23)
INSERT INTO SampleData VALUES (400, 10)
INSERT INTO SampleData VALUES (400, 11)
INSERT INTO SampleData VALUES (400, 14)
INSERT INTO SampleData VALUES (400, 16)



SELECT 
        t1.Location,
        t1.Number      AS startofgroup, 
       MIN(t2.Number) AS endofgroup 
FROM   (SELECT Number , Location
        FROM   SampleData tbl1 
        WHERE  NOT EXISTS(SELECT * 
                          FROM   SampleData tbl2 
                          WHERE  tbl1.Number - tbl2.Number = 1
                                 and tbl1.Location = tbl2.Location)) t1 
       INNER JOIN (SELECT Number , Location
                   FROM   SampleData tbl1 
                   WHERE  NOT EXISTS(SELECT * 
                                     FROM   SampleData tbl2 
                                     WHERE  tbl2.Number - tbl1.Number = 1
                                     and tbl1.Location = tbl2.Location)) t2 
         ON t1.Number <= t2.Number 
            and t1.Location = t2.Location
GROUP  BY 
    t1.Location,
    t1.Number 
ORDER BY 
   Location,
   startofgroup

输出

Location    startofgroup endofgroup
----------- ------------ -----------
300         15           18
300         21           23
400         10           11
400         14           14
400         16           16

。它是清单 2 的修改版本。用于识别岛屿的基于集合的解决方案。来自序列号中的孤岛和间隙作者:Alexander Kozak

如果您正在寻找 SQL Server 2005 及更高版本的更多选项,您应该搜索短语“Itzik本甘间隙和岛屿"

Here's as relatively portable SQL solution since you didn't specify the DB

Create Table  SampleData  (Location int, Number Int)
INSERT INTO SampleData VALUES (300, 15)
INSERT INTO SampleData VALUES (300, 16)
INSERT INTO SampleData VALUES (300, 17)
INSERT INTO SampleData VALUES (300, 18)
INSERT INTO SampleData VALUES (300, 21)
INSERT INTO SampleData VALUES (300, 22)
INSERT INTO SampleData VALUES (300, 23)
INSERT INTO SampleData VALUES (400, 10)
INSERT INTO SampleData VALUES (400, 11)
INSERT INTO SampleData VALUES (400, 14)
INSERT INTO SampleData VALUES (400, 16)



SELECT 
        t1.Location,
        t1.Number      AS startofgroup, 
       MIN(t2.Number) AS endofgroup 
FROM   (SELECT Number , Location
        FROM   SampleData tbl1 
        WHERE  NOT EXISTS(SELECT * 
                          FROM   SampleData tbl2 
                          WHERE  tbl1.Number - tbl2.Number = 1
                                 and tbl1.Location = tbl2.Location)) t1 
       INNER JOIN (SELECT Number , Location
                   FROM   SampleData tbl1 
                   WHERE  NOT EXISTS(SELECT * 
                                     FROM   SampleData tbl2 
                                     WHERE  tbl2.Number - tbl1.Number = 1
                                     and tbl1.Location = tbl2.Location)) t2 
         ON t1.Number <= t2.Number 
            and t1.Location = t2.Location
GROUP  BY 
    t1.Location,
    t1.Number 
ORDER BY 
   Location,
   startofgroup

Output

Location    startofgroup endofgroup
----------- ------------ -----------
300         15           18
300         21           23
400         10           11
400         14           14
400         16           16

Its a modified version of Listing 2. A set-based solution for identifying islands. From Islands and Gaps in Sequential Numbers by Alexander Kozak

If you're looking for more options with SQL Server 2005 and later you should search for the phrase "Itzik Ben-Gan gaps and islands"

浮云落日 2024-11-21 18:58:33

好吧,如果您使用的 RDBMS 支持 lag() 函数,那么这应该会告诉您中断在哪里。然后,您应该能够使用它以及一些 case 语句并仔细使用 min() 和 max() 函数来获得您想要的查询。

select location, lag_number as startnumber, number as endnumber
from(select location, number, lag_number
from(
    select location, number
    , lag(number) over (partition by location order by number) as lag_number
    from table
    )a
    where number is not null and lag_number is not null
)b
where number-lag_number>1 order by 1,2,3;

Well, if you're using an RDBMS that supports the lag() function, then this should tell you where the breaks are. You should then be able to use this, along with some case statements and careful use of the min() and max() functions, to get the query that you want.

select location, lag_number as startnumber, number as endnumber
from(select location, number, lag_number
from(
    select location, number
    , lag(number) over (partition by location order by number) as lag_number
    from table
    )a
    where number is not null and lag_number is not null
)b
where number-lag_number>1 order by 1,2,3;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文