[SQL] SQL : 연속 기록에 그룹으로
SQLSQL : 연속 기록에 그룹으로
약간 까다로운 SQL 질문 (우리는 SQL 서버 2000을 실행하는).
나는 STORECOUNT을 다음과 같은 테이블이 -
WeekEndDate StoreCount
2010-07-25 359
2010-07-18 359
2010-07-11 358
2010-07-04 358
2010-06-27 358
2010-06-20 358
2010-06-13 358
2010-06-06 359
2010-05-30 360
2010-05-23 360
2010-05-16 360
나는 다음과 같은 출력으로이 켜려고합니다 -
StartDate EndDate StoreCount
2010-07-18 2010-07-25 359
2010-06-13 2010-07-11 358
2010-06-06 2010-06-06 359
2010-05-16 2010-05-30 360
당신이 볼 수 있듯이 그들이 함께 순서대로 실행으로, 나는 단지로, 그룹에 매장 수를 꿔.
해결법
-
==============================
1.여기에 캔에서 킥입니다 만 그것은 SS2k에서 사용할 수없는 구문 수 있습니다. 내가 주변에 더 이상 SS의 해당 버전이없는 것처럼 실제로 오라클에 작성되었습니다. 유일한 캐치는이 (가) 선택의 선택이 될 수 ... (내가 SS2k을 사용 했으므로하면서 기능을 사용할 수 다시 다음하지 않았다 기억하기 어렵다 그래서는이있었습니다.)
여기에 캔에서 킥입니다 만 그것은 SS2k에서 사용할 수없는 구문 수 있습니다. 내가 주변에 더 이상 SS의 해당 버전이없는 것처럼 실제로 오라클에 작성되었습니다. 유일한 캐치는이 (가) 선택의 선택이 될 수 ... (내가 SS2k을 사용 했으므로하면서 기능을 사용할 수 다시 다음하지 않았다 기억하기 어렵다 그래서는이있었습니다.)
select min(weekenddate) as start_date, end_date, storecount from ( select s1.weekenddate , (select max(weekenddate) from store_stats s2 where s2.storecount = s1.storecount and not exists (select null from store_stats s3 where s3.weekenddate < s2.weekenddate and s3.weekenddate > s1.weekenddate and s3.storecount <> s1.storecount) ) as end_date , s1.storecount from store_stats s1 ) result group by end_date, storecount order by 1 desc START_DATE END_DATE STORECOUNT ---------- ---------- ---------- 2010-07-18 2010-07-25 359 2010-06-13 2010-07-11 358 2010-06-06 2010-06-06 359 2010-05-16 2010-05-30 360
-
==============================
2.사용 커서. 나는 쿼리를 사용하여 sql2k에서 그것을 할 방법을 모르겠어요.
사용 커서. 나는 쿼리를 사용하여 sql2k에서 그것을 할 방법을 모르겠어요.
DECLARE @w datetime DECLARE @s int DECLARE @prev_s int DECLARE @start_w datetime DECLARE @end_w datetime CREATE TABLE #zz(start datetime, [end] datetime, StoreCount int) DECLARE a_cursor CURSOR FOR SELECT WeekEndDate, StoreCount FROM Line ORDER BY WeekEndDate DESC, StoreCount OPEN a_cursor FETCH NEXT FROM a_cursor INTO @w, @s WHILE @@FETCH_STATUS = 0 BEGIN IF @end_w IS NULL BEGIN SET @end_w = @w SET @start_w = @w SET @prev_s = @s END ELSE IF @prev_s <> @s BEGIN INSERT INTO #zz values(@start_w, @end_w, @prev_s) SET @end_w = @w SET @start_w = @w SET @prev_s = @s END ELSE SET @start_w = @w FETCH NEXT FROM a_cursor INTO @w, @s END -- add last one INSERT INTO #zz values(@start_w, @end_w, @prev_s) CLOSE a_cursor DEALLOCATE a_cursor SELECT * FROM #zz ORDER BY 1 DESC DROP TABLE #zz
-
==============================
3.좋아, 여기에 나의 이동합니다.
좋아, 여기에 나의 이동합니다.
DECLARE @curDate DATETIME = (SELECT MIN(WeekEndDate) FROM Table_1); DECLARE @curCount INT = (SELECT StoreCount FROM Table_1 WHERE WeekEndDate = @curDate); DECLARE @sDate DATETIME = GETDATE() DECLARE @eDate DATETIME = 0 WHILE @eDate < (SELECT MAX(WeekEndDate) FROM Table_1) BEGIN SELECT @sDate = (SELECT WeekEndDate AS StartDate FROM Table_1 WHERE WeekEndDate = @curDate) -- SELECT START DATE -- NOW GET THE END DATE IN THIS GROUP DECLARE @d1 DATETIME = @curDate DECLARE @d2 DATETIME = @curDate DECLARE @loop INT = 1 WHILE @loop = 1 BEGIN IF ((SELECT StoreCount FROM Table_1 WHERE WeekEndDate = @d1) <> @curCount OR @d1 = (SELECT MAX(WeekEndDate) FROM Table_1)) BEGIN SELECT @eDate = (SELECT TOP(1) WeekEndDate FROM Table_1 WHERE StoreCount = @curCount AND WeekEndDate = @d2 ORDER BY WeekEndDate DESC) SELECT @loop = 0 END ELSE BEGIN SELECT @d2 = @d1 SELECT @d1 = (SELECT TOP(1) WeekEndDate FROM Table_1 WHERE WeekEndDate > @d1 ORDER BY WeekEndDate) END END SELECT @sDate AS StartDate, @eDate AS EndDate, @curCount AS StoreCount -- DO QHATEVER YOU NEED TO DO WITH THE RECORDS HERE SELECT TOP(1) @curDate = WeekEndDate, @curCount = StoreCount FROM Table_1 WHERE WeekEndDate > @eDate GROUP BY WeekEndDate, StoreCount ORDER BY WeekEndDate ASC END
-
==============================
4.나는 이것을 설명하는 방법을 잘 모르겠지만, 주어진 작은 데이터 세트에 대해 원하는 결과를 줄 것으로 보인다. 본질적으로,이 값이 변경 시리즈의 포인트를 감지합니다.
나는 이것을 설명하는 방법을 잘 모르겠지만, 주어진 작은 데이터 세트에 대해 원하는 결과를 줄 것으로 보인다. 본질적으로,이 값이 변경 시리즈의 포인트를 감지합니다.
내가 쿼리 계획을보고하지 않은, 고통스러운 수 있습니다.
구문은 SQL 서버 2K와 호환되어야하며,이 Sybase 서버에 시도.
SELECT x.StartDate , MIN( y.EndDate ) AS EndDate , x.StoreCount FROM ( SELECT wed1.WeekEndDate AS StartDate , wed1.StoreCount FROM wed wed1 LEFT JOIN wed wed2 ON wed1.WeekEndDate = DATEADD( DAY, 7, wed2.WeekEndDate ) WHERE wed1.StoreCount != ISNULL( wed2.StoreCount, wed1.StoreCount - 1 ) ) x, ( SELECT wed1.WeekEndDate AS EndDate FROM wed wed1 LEFT JOIN wed wed2 ON wed1.WeekEndDate = DATEADD( DAY, -7, wed2.WeekEndDate ) WHERE wed1.StoreCount != ISNULL( wed2.StoreCount, wed1.StoreCount - 1 ) ) y WHERE y.EndDate >= x.StartDate GROUP BY x.StartDate HAVING x.StartDate = MIN( x.StartDate ) ORDER BY 1 DESC StartDate EndDate StoreCount ------------ ------------ ----------- Jul 18 2010 Jul 25 2010 359 Jun 13 2010 Jul 11 2010 358 Jun 6 2010 Jun 6 2010 359 May 16 2010 May 30 2010 360
-
==============================
5.이 간단한 해결책을 시도해보십시오 :
이 간단한 해결책을 시도해보십시오 :
create table x (weekEndDate char(10), storeCount int); insert into x values ('2010-07-25',359), ('2010-07-18',359), ('2010-07-11',358), ('2010-07-04',358), ('2010-06-27',358), ('2010-06-20',358), ('2010-06-13',358), ('2010-06-06',359), ('2010-05-30',360), ('2010-05-23',360), ('2010-05-16',360); select min(weekenddate) as startdate, max(weekenddate) as enddate, min(storecount) as storecount from (select weekenddate, storecount, concat(row_number() over (order by weekenddate) -row_number() over (partition by storecount order by weekenddate),'|',storecount) as groupkey from x) w group by groupkey order by startdate desc;
sqlfiddle
from https://stackoverflow.com/questions/3410687/sql-group-by-on-consecutive-records by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 이 행의 위치를 포함하도록 업데이트 칼럼 (0) | 2020.07.04 |
---|---|
[SQL] 삽입 여기서 일하지 않는 무시 내 테이블에서 중복 레코드를 방지하는 방법 (0) | 2020.07.04 |
[SQL] 이 SELECT 쿼리는 마무리 180 초 소요 (0) | 2020.07.04 |
[SQL] 지난 일요일 찾기 (0) | 2020.07.03 |
[SQL] 절에 SQL에 튜플을 사용하여 (0) | 2020.07.03 |