2013-08-21 5 views
12

का हिस्सा द्वारा मैं अपनी तालिका में डेटा निम्नलिखित है:एसक्यूएल समूह स्ट्रिंग

URL   TIME DATE 
-------------------------------------- 
/x   11  2013-08-01 
/x   11  2013-08-01 
/pl/  11  2013-08-01 
/pl/  11  2013-08-03 
/pl/XXX/ 11  2013-08-01 
/pl/XXX/ 11  2013-08-04 
/pl/XXX/1 11  2013-08-01 
/pl/XXX/2 11  2013-08-01 
/pl/YYY/ 11  2013-08-01 
/pl/YYY/1 11  2013-08-01 
/pl/YYY/2 11  2013-08-04 
/pl/YYY/3 11  2013-08-04 

वहाँ यूआरएल द्वारा समूह के लिए एक रास्ता एसक्यूएल सर्वर में तीसरे स्लैश (/) तक है? दुर्भाग्य से रिकॉर्ड मौजूद है जिसमें तीन से कम है। एक स्ट्रिंग में स्लैश की संख्या की गणना करने के लिए

+0

आपको यह प्रश्न पढ़ना चाहिए: http://stackoverflow.com/questions/8726111/sql-server-find-nth-occurrence-in-a-string – MarcinJuraszek

+0

क्या यह एक, दो या तीन स्लैश है: 'pl/XXX '? मैं पूछता हूं क्योंकि यह '/ pl/XXX /' जैसा ही पथ हो सकता है। –

+0

@TimSchmelter सभी डेटा स्लैश के साथ शुरू होता है इसलिए यह कोई समस्या नहीं है –

उत्तर

9

एक चाल है:

len(url) - len(replace(url,'/','')) 

तो आप charindex तीन बार उपयोग कर सकते हैं तीसरे स्लैश की स्थिति का पता लगाने के लिए:

select BeforeThirdSlash 
,  max([date]) 
from (
     select case 
       when len(url) - len(replace(url,'/','')) < 3 then url 
       else substring(url, 1, charindex('/', url, charindex('/', 
         url, charindex('/', url)+1)+1)-1) 
       end as BeforeThirdSlash 
     ,  * 
     from @t 
     ) as SubQueryAlias 
group by 
     BeforeThirdSlash 

Live example at SQL Fiddle.

2

आप / की प्रत्येक स्थिति की स्थिति पा सकते हैं और MAX(position) पर ट्रिम कर सकते हैं - तीसरेको मानते हुए डेटा के अनुसारअंतिम / है।

DECLARE @tbl TABLE (u VARCHAR(255), t INT, d DATE) 

INSERT INTO @tbl (u, t, d) VALUES 
('/x',   11,  '2013-08-01'), 
('/x',   11,  '2013-08-01'), 
('/pl/',  11,  '2013-08-01'), 
('/pl/',  11,  '2013-08-03'), 
('/pl/XXX/', 11,  '2013-08-01'), 
('/pl/XXX/', 11,  '2013-08-04'), 
('/pl/XXX/1', 11,  '2013-08-01'), 
('/pl/XXX/2', 11,  '2013-08-01'), 
('/pl/YYY/', 11,  '2013-08-01'), 
('/pl/YYY/1', 11,  '2013-08-01'), 
('/pl/YYY/2', 11,  '2013-08-04'), 
('/pl/YYY/3', 11,  '2013-08-04') 

;WITH split AS (
    SELECT u, 1 s, CHARINDEX('/', u) p 
    FROM @tbl 
    UNION ALL 
    SELECT u, p + 1, CHARINDEX('/', u, p + 1) 
    FROM split 
) 

SELECT LEFT(t.u, split.i), MAX(t.t), MAX(t.d) 
FROM @tbl t 
JOIN (
    SELECT u, MAX(p) i 
    FROM split 
    GROUP BY u 
) split ON split.u = t.u 
GROUP BY LEFT(t.u, split.i) 
CTE करने के लिए एक मामूली समायोजन के साथ

आप आवृत्तियां

DECLARE @n INT = 3 -- 'nth occurence' 

;WITH split AS (
    SELECT u, CHARINDEX('/', u) i, 1 r 
    FROM (
     SELECT DISTINCT u 
     FROM @tbl 
    ) t 
    WHERE CHARINDEX('/', u) > 0 
    UNION ALL 
    SELECT u, CHARINDEX('/', u, i + 1), r + 1 
    FROM split 
    WHERE r < @n 
    AND CHARINDEX('/', u, i + 1) > 0 
) 

SELECT LEFT(t.u, split.i) u, MAX(t.t) t , MAX(t.d) d 
FROM @tbl t 
JOIN split ON split.u = t.u 
GROUP BY LEFT(t.u, split.i) 

sql fiddle demo

3

एक सरल अभिव्यक्ति आप हड़पने तीसरे '/' चरित्र पर निर्भर सबस्ट्रिंग इस प्रकार है देता है कि नियंत्रित कर सकते हैं:

case 
    when patindex('%/%/%/%', url) = 0 then url 
    else left(url,charindex('/',url,charindex('/',url,charindex('/',url)+1)+1)) 
end 

patindex चेक करता है कि कम से कम तीन स्लेश हैं; left एक दूसरे को शामिल करने के लिए सबस्ट्रिंग निष्कर्ष निकालता है।

हाथ में इस अभिव्यक्ति के साथ

, लेखन एक group by सरल है:

SELECT 
    url3, max(tm), max(dt) 
FROM (
    SELECT 
     CASE 
      WHEN patindex('%/%/%/%', url) = 0 THEN url 
      ELSE left(url,charindex('/',url,charindex('/',url,charindex('/',url)+1)+1)) 
     END AS url3 
    , tm 
    , dt 
    FROM test 
) x 
GROUP BY url3 

Demo on SqlFiddle

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