一个稍微棘手的SQL问题(我们正在运行SQL Server 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
正如你所看到的,我只是想按照顺序一起运行来分组商店数量。
答案 0 :(得分:12)
这是罐头上的一个踢,只有它可能有SS2k中没有的语法。它实际上写在Oracle上,因为我不再拥有那个版本的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
答案 1 :(得分:1)
使用光标。我不知道如何使用查询在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
答案 2 :(得分:1)
我不确定如何解释这一点,但它似乎给出了给定的小数据集所需的结果。实质上,它会检测系列中值变化的点。
我没有看过查询计划,可能会很痛苦。
在Sybase服务器上试用,因此语法应该与SQL Server 2K兼容。
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
答案 3 :(得分:1)
好的,这是我的理由。
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 :(得分:-1)
try this simple solution:
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;