2010-08-04 13 views
12

थोड़ा मुश्किल SQL प्रश्न (हम SQL सर्वर 2000 चला रहे हैं)।एसक्यूएल: समूह द्वारा कॉन्सेक्टीव रिकॉर्ड्स

मैं निम्न तालिका, STORECOUNT है -

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 

आप देख सकते हैं, मैं समूह के लिए इच्छुक हूँ दुकान में गिना जाता है -

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 

मैं निम्नलिखित उत्पादन में इस चालू करना चाहते हैं , जैसे ही वे अनुक्रम में एक साथ चलते हैं।

+2

# 359 के लिए, तुम कैसे जानते जून में तारीख अकेले खड़े हैं, कि यह अगले तारीख के साथ कनेक्ट नहीं करता है कि है जुलाई (18 वें) में? –

+0

क्योंकि रिकॉर्ड अवरोही तिथि क्रम में हैं –

+0

@ क्रैग्स: पर्याप्त नहीं है - नियम के बिना, हम रिकॉर्ड को अलग नहीं कर सकते हैं। –

उत्तर

11

यहां पर एक किक है, केवल सिंटैक्स एसएस 2 के में उपलब्ध नहीं हो सकता है। यह वास्तव में ओरेकल पर लिखा गया था क्योंकि मेरे पास एसएस के उस संस्करण के आसपास अब नहीं है। केवल पकड़-चुने का चयन हो सकता है ... (यह कुछ समय के बाद से मैं 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

पैट्रिक - मुझे लगता है कि यह अच्छा है सिवाय इसके कि आपको FROM क्वेरी के परिणामों के लिए उपनाम जोड़ने की आवश्यकता है। End_date, storecount' द्वारा 'समूह' से ऊपर की रेखा, 'से' '' 'में बदलें 'परिणाम'। मेरे लिए एक योग्यता; मेरे पास SQL ​​Server 2000 भी नहीं है। – bobs

+0

शानदार पैट्रिक - जैसा कि बोब्स ने इंगित किया, मुझे जोड़ने की ज़रूरत थी, उपनाम था, और यह पूरी तरह से काम करता था। बहुत बढ़िया। –

+0

मुझे हर बार मिलता है। ओरेकल उन उपनामों की परवाह नहीं करता है; एसक्यूएल सर्वर करता है। फिक्स के लिए धन्यवाद। –

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 
+0

प्रश्न पर मेरी टिप्पणियां देखें - # 35 9 में सही मूल्य नहीं होंगे। –

1

मुझे यकीन नहीं है कि यह कैसे समझाया जाए, लेकिन ऐसा लगता है कि छोटे डेटासेट के लिए वांछित परिणाम देना है। संक्षेप में, यह श्रृंखला में बिंदुओं का पता लगाता है जहां मूल्य बदलते हैं।

मैंने क्वेरी प्लान को नहीं देखा है, दर्दनाक हो सकता है।

एक साइबेस सर्वर पर कोशिश की, तो वाक्यविन्यास SQL ​​सर्वर 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 
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 
-1

इस सरल समाधान का प्रयास करें:

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

संबंधित मुद्दे