March 18, 2015 at 1:16 pm
well i doinked aroudn getting the data, but row number snot going to find consecutive montsh... here;s the data as a consumable post at least.
;WITH MyCTE([PERSON ID],[MONTH ORDERED],[Note])
AS
(
SELECT 'JD12345','4','' UNION ALL
SELECT 'JD12345','7','' UNION ALL
SELECT 'JD12345','8','Note: JD12345 should be excluded entirely' UNION ALL
SELECT 'JD12348','5','' UNION ALL
SELECT 'JD12348','6','this record should be captured' UNION ALL
SELECT 'JD12348','7','this record should be captured' UNION ALL
SELECT 'JD12348','8','this record should be captured' UNION ALL
SELECT 'JD12348','9','' UNION ALL
SELECT 'JD12363','12','Note: JD12363 should be excluded entirely' UNION ALL
SELECT 'JD12374','3','' UNION ALL
SELECT 'JD12374','4','this record should be captured' UNION ALL
SELECT 'JD12374','5',''
)
SELECT * FROM MyCTE
ORDER BY [PERSON ID], [MONTH ORDERED]
Lowell
March 18, 2015 at 1:26 pm
Thanks,, I already tried rownumber over partion and that didn't work. The notes comments was just for clarification of what I need to capture, and is not present in table.
Thanks!
March 18, 2015 at 2:25 pm
Do you realize that this is a gaps and islands problem?
This is a possible approach using ROW_NUMBER(). Maybe someone can get a better solution as I don't like to sort twice. This assumes that your months only grow and won't reset after 12.
CREATE TABLE #Sample(
[PERSON_ID] char(7),
[MONTH_ORDERED] int,
[Note] varchar(100)
)
INSERT INTO #Sample
SELECT 'JD12345','4','' UNION ALL
SELECT 'JD12345','7','' UNION ALL
SELECT 'JD12345','8','Note: JD12345 should be excluded entirely' UNION ALL
SELECT 'JD12348','5','' UNION ALL
SELECT 'JD12348','6','this record should be captured' UNION ALL
SELECT 'JD12348','7','this record should be captured' UNION ALL
SELECT 'JD12348','8','this record should be captured' UNION ALL
SELECT 'JD12348','9','' UNION ALL
SELECT 'JD12363','12','Note: JD12363 should be excluded entirely' UNION ALL
SELECT 'JD12374','3','' UNION ALL
SELECT 'JD12374','4','this record should be captured' UNION ALL
SELECT 'JD12374','5','' ;
WITH CTE AS(
SELECT *,
MONTH_ORDERED - ROW_NUMBER() OVER(PARTITION BY PERSON_ID ORDER BY MONTH_ORDERED) grouper,
ROW_NUMBER() OVER(PARTITION BY PERSON_ID ORDER BY MONTH_ORDERED) rnfirst,
ROW_NUMBER() OVER(PARTITION BY PERSON_ID ORDER BY MONTH_ORDERED DESC) rnlast
FROM #Sample
)
SELECT [PERSON_ID],
[MONTH_ORDERED],
Note
FROM CTE
WHERE rnfirst > 1
AND rnlast > 1
AND PERSON_ID IN(SELECT PERSON_ID
FROM CTE
GROUP BY PERSON_ID, grouper
HAVING COUNT(*) >= 3)
ORDER BY [PERSON_ID], [MONTH_ORDERED]
GO
DROP TABLE #Sample
March 18, 2015 at 2:36 pm
Thanks Luis.
I tried your code on my sample data and it produced 0 output records.
March 18, 2015 at 2:55 pm
I was able to get this to work. The sample records I gave you above were a subset of fields from the original table. I created a new table with only the Person ID and Month Ordered fields from original table and it worked!!!
Thanks for your help Luis! 🙂
March 18, 2015 at 3:05 pm
Don't thank me until you fully understand it.
There are lots of articles that talk about gaps and islands problems, some of them show better solutions performance wise but I like this one because I find it easier to understand and the performance is good.
Viewing 6 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply