MySQL

2012-09-05 11 views
7

का उपयोग कर निरंतर श्रेणियों को कैसे समूहित करें मेरे पास एक सारणी है जिसमें श्रेणियां, तिथियां और दरें शामिल हैं। प्रत्येक श्रेणी में अलग-अलग तिथियों के लिए अलग-अलग दरें हो सकती हैं, एक श्रेणी में किसी दिए गए दिनांक पर केवल एक दर हो सकती है।MySQL

Id  CatId Date  Rate 
------ ------ ------------ --------- 
000001  12 2009-07-07  1 
000002  12 2009-07-08  1 
000003  12 2009-07-09  1 
000004  12 2009-07-10  2 
000005  12 2009-07-15  1 
000006  12 2009-07-16  1 
000007  13 2009-07-08  1 
000008  13 2009-07-09  1 
000009  14 2009-07-07  2 
000010  14 2009-07-08  1 
000010  14 2009-07-10  1 

अनोखा सूचकांक (CatID, तिथि, दर) मैं समूह के सभी निरंतर दिनांकों श्रेणियों के लिए प्रत्येक श्रेणी के लिए पसंद है और रख केवल शुरू करते हैं और सीमा की समाप्ति होगी। पिछले उदाहरण के लिए, हम होगा:

CatId Begin   End   Rate 
------ ------------ ------------ --------- 
12  2009-07-07 2009-07-09  1 
12  2009-07-10 2009-07-10  2 
12  2009-07-15 2009-07-16  1 
13  2009-07-08 2009-07-09  1 
14  2009-07-07 2009-07-07  2 
14  2009-07-08 2009-07-08  1 
14  2009-07-10 2009-07-10  1 

मैं the forum में एक ऐसी ही समाधान है जो वास्तव में परिणाम

WITH q AS 
     (
     SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY CatId, Rate ORDER BY [Date]) AS rnd, 
       ROW_NUMBER() OVER (PARTITION BY CatId ORDER BY [Date]) AS rn 
     FROM my_table 
     ) 
SELECT CatId AS catidd, MIN([Date]) as beginn, MAX([Date])as endd, Rate 
FROM q 
GROUP BY CatId, rnd - rn, Rate 

SQL FIDDLE SEE मैं mysql में एक ही बात कर सकते हैं कैसे नहीं दिया पाया ? कृपया मदद करें!

+0

क्यों '(CatID, दर) = के लिए अपने उदाहरण शो करता है (14,1) 'अंतर्निहित तालिका में' 200 9-07-09 'नहीं होने पर '200 9-07-08' से' 200 9 -10-10-10 'तक की परिणामी सीमा? सी.एफ़ '(CatId, दर) = (12,1)', जो इसकी असंतोष के कारण दो परिणामी श्रेणियों का उत्पादन करता है। – eggyal

+0

धन्यवाद eggyal, अब यह – Fouzi

उत्तर

6

MySQL विश्लेषणात्मक कार्यों का समर्थन नहीं करता है, लेकिन आप user-defined variables साथ इस तरह के व्यवहार का अनुकरण कर सकते हैं:

SELECT CatID, Begin, MAX(Date) AS End, Rate 
FROM (
    SELECT my_table.*, 
      @f:=CONVERT(
      IF(@c<=>CatId AND @r<=>Rate AND DATEDIFF(Date, @d)=1, @f, Date), DATE 
      ) AS Begin, 
      @c:=CatId, @d:=Date, @r:=Rate 
    FROM  my_table JOIN (SELECT @c:=NULL) AS init 
    ORDER BY CatId, Rate, Date 
) AS t 
GROUP BY CatID, Begin, Rate 

sqlfiddle पर यह देखें।

+0

उम्मीद के अनुसार काम करने के लिए लगता है! बहुत बहुत धन्यवाद! – Fouzi

+1

'<=>' का अर्थ क्या है? –

+1

@vanabel: यह MySQL है [ऑपरेटर के बराबर सुरक्षित] [http://dev.mysql.com/doc/en/comparison-operators.html#operator_equal-to)। – eggyal

3
SELECT catid,min(ddate),max(ddate),rate 
FROM (
    SELECT 
     Catid, 
     Ddate, 
     rate, 
     @rn := CASE WHEN (@prev <> rate 
      or DATEDIFF(ddate, @prev_date)>1) THEN @rn+1 ELSE @rn END AS rn, 
     @prev := rate, 
     @prev_id := catid , 
     @prev_date :=ddate 
    FROM (
     SELECT CatID,Ddate,rate 
     FROM rankdate 
     ORDER BY CatID, Ddate) AS a , 
     (SELECT @prev := -1, @rn := 0, @prev_id:=0 ,@prev_date:=-1) AS vars  

) T1 group by catid,rn 

नोट: लाइन (: = -1, @rn: = 0, @prev_id: = 0, @ prev_date: @prev का चयन करें = - 1) के रूप में वार्स Mysql कार्यस्थान में आवश्यक नहीं है, लेकिन यह PHP mysql_query फ़ंक्शन में है।

SQL FIDDLE HERE

+0

को सही किया गया है यदि हम आपकी क्वेरी वापसी आईडी ('000004' के साथ रिकॉर्ड हटाते हैं (शुरू: 200 9-07-07, अंत: 200 9 -16-16, दर: 1) यह सही नहीं है क्योंकि वहां कोई सही नहीं है अंतराल, इसे वापस करना चाहिए (शुरू: 200 9-07-07, अंत: 200 9-07-09, दर: 1) और (शुरू: 200 9-07-15, अंत: 200 9 -16-16, दर: 1)। [एसक्यूएल फिडले यहां] (http://sqlfiddle.com/#!2/513b2/1) – Fouzi

+0

@ बुशेलबचिर, मैंने जवाब संपादित किया है। इस मामले में, आपके द्वारा उल्लेख की गई स्थिति को पूरा करने के लिए डेटीफ की स्थिति शामिल करने की आवश्यकता है। – sel

+0

आप कहीं भी '@ prev_id' का परीक्षण नहीं कर रहे हैं ... क्या होता है यदि समान 'दर' के साथ दो संगत तिथियों में अलग-अलग' CatId' है? – eggyal

0

मुझे पता है कि मुझे देर हो चुकी है, अभी भी एक समाधान पोस्ट कर रहा है जो मेरे लिए काम करता है। एक ही मुद्दा था, यहाँ कैसे मैं समझ गया

मिले पर चर

SELECT MIN(id) AS id, MIN(date) AS date, MIN(state) AS state, COUNT(*) cnt 
FROM (
    SELECT @r := @r + (@state != state OR @state IS NULL) AS gn, 
      @state := state AS sn, 
      s.id, s.date, s.state 
    FROM (
      SELECT @r := 0, 
        @state := NULL 
      ) vars, 
      t_range s 
    ORDER BY 
      date, state 
    ) q 
GROUP BY gn 

अधिक जानकारी का उपयोग कर एक अच्छा समाधान है: https://explainextended.com/2009/07/24/mysql-grouping-continuous-ranges/