How to determine size of continious range for given criteria?
I have a positions table in SQL Server 2008R2 (definition below).
In the system boxes there are positions.
I have a requirement to find a box, which has X free positions remaining. However, the X positions must be continuous (left to right, top to bottom i.e. ascending PositionID).
It has been simple to construct a query that finds a box with X positions free. I now have the problem of determining if the positions are continuous.
Any suggestions on a TSQL based solution?
Table Definition
` CREATE TABLE [dbo].[Position]( [PositionID] [int] IDENTITY(1,1) NOT NULL, [BoxID] [int] NOT NULL, [pRow] [int] NOT NULL, [pColumn] [int] NOT NULL, [pRowLetter] [char](1) NOT NULL, [pColumnLetter] [char](1) NOT NULL, [SampleID] [int] NULL, [ChangeReason] [nvarchar](4000) NOT NULL, [LastUserID] [int] NOT NULL, [TTSID] [bigint] NULL, CONSTRAINT [PK_Position] PRIMARY KEY CLUSTERED ( [PositionID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]`
Edit
http://pastebin.com/V8DLiucN - pastebin link with sample positions for 1 box (all positions empty in sample data)
Edit 2
A开发者_如何学C 'free' position is one with SampleID = null
DECLARE @AvailableSlots INT
SET @AvailableSlots = 25
;WITH OrderedSet AS (
SELECT
BoxID,
PositionID,
Row_Number() OVER (PARTITION BY BoxID ORDER BY PositionID) AS rn
FROM
Position
WHERE
SampleID IS NULL
)
SELECT
BoxID,
COUNT(*) AS AvailableSlots,
MIN(PositionID) AS StartingPosition,
MAX(PositionID) AS EndingPosition
FROM
OrderedSet
GROUP BY
PositionID - rn,
BoxID
HAVING
COUNT(*) >= @AvailableSlots
The trick is the PositionID - rn
(row number) in the GROUP BY
statement. This works to group together continuous sets... and from there it's easy to just do a HAVING
to limit the results to the BoxID
s that have the required amount of free slots.
精彩评论