2012-04-06 4 views
6

नीचे दिया गया कोड हल किए गए टिकटों की संख्या और अवधि के लिए खुले टिकटों की संख्या देता है (अवधि YYYY, WW) कुछ निश्चित दिनों में वापस जा रही है। उदाहरण के लिए यदि @NoOfDays 7:डेटा सेट से एक ट्रेंड लाइन बनाना SQL

हल हो गया है। खोला सप्ताह | वर्ष | अवधि

56 | 30 | 13 | 2012 | 2012, 13

237 | 222 | 14 | 2012 | 2012, 14

'हल' और 'खोला' लाइनों (वाई) से अधिक अवधि (x) पर graphed हैं। मैं एक और कॉलम 'ट्रेंड' जोड़ना चाहता हूं जो कि उस अवधि को वापस कर देगा जो अवधि के दौरान घिरा हुआ होगा, एक प्रवृत्ति रेखा (सरल रैखिक प्रतिगमन) होगी। I प्रवृत्ति के लिए डेटा स्रोत के रूप में मूल्यों के दोनों सेटों का उपयोग करना चाहते हैं।

SELECT a.resolved, b.opened, a.weekClosed AS week, a.yearClosed AS year, 
    CAST(a.yearClosed as varchar(5)) + ', ' + CAST(a.weekClosed as varchar(5)) AS period 
FROM 
    (SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS resolved, { fn WEEK(date_closed) } AS weekClosed, { fn YEAR(date_closed) } AS yearClosed 
    FROM v_rpt_Service 
    WHERE (date_closed >= DateAdd(Day, DateDiff(Day, 0, GetDate()) - @NoOfDays, 0)) 
    GROUP BY { fn WEEK(date_closed) }, { fn YEAR(date_closed) }) AS a 
LEFT OUTER JOIN 
    (SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS opened, { fn WEEK(date_entered) } AS weekEntered, { fn YEAR(date_entered) 
    } AS yearEntered 
    FROM v_rpt_Service AS v_rpt_Service_1 
    WHERE  (date_entered > = DateAdd(Day, DateDiff(Day, 0, GetDate()) - @NoOfDays, 0)) 
    GROUP BY { fn WEEK(date_entered) }, { fn YEAR(date_entered) }) AS b ON a.weekClosed = b.weekEntered AND a.yearClosed = b.yearEntered 
ORDER BY year, week 

संपादित करें::

serc.carleton.edu/files/mathyouneed/best_fit_line_dividing.pdf के अनुसार, ऐसा लगता है कि मैं तोड़ने के लिए चाहते हैं

इस कोड को मेरे पास है आधे में डेटा, फिर औसत की गणना करें। तो मुझे y = mx + b का उपयोग करके 'ट्रेंड' में वापस आने के लिए आवश्यक मूल्यों की गणना करने के लिए सबसे अच्छी फिट लाइन खोजने और ढलान और वाई-अवरोध का उपयोग करने की आवश्यकता है?

मुझे पता है कि एसक्यूएल में यह बहुत संभव है, हालांकि, प्रोग्राम जो मैं एसक्यूएल डाल रहा हूं उसमें सीमाएं हैं जो मैं कर सकता हूं।

लाल और नीले बिंदुएं संख्याएं हैं जो मैं अब लौट रहा हूं (खोला और हल किया गया)। बैंगनी रेखा बनाने के लिए मुझे 'प्रवृत्ति' में हर अवधि के लिए एक मूल्य वापस करने की जरूरत है। (इस छवि काल्पनिक है)

Hypothetical Chart

+0

क्या यह एमएस एसक्यूएल सर्वर के लिए है, या एक अलग आरडीबीएमएस के लिए है? –

+0

एमएस एसक्यूएल सर्वर सही है। –

उत्तर

1

मैं इसे समझ से बाहर। मैंने डेटा को कई व्युत्पन्न तालिकाओं और उप प्रश्नों में विभाजित किया, अनिवार्य रूप से डेटा को आधा में विभाजित किया।

*(each row is a week)* 
y1 = average of data first half 
y2 = average of data second half 
x1 = 1/4 of number of weeks 
x2 = 3/4 of number of weeks 
m = (y1-y2)/(x1-x2) 
b = y2 - (m * x2) 
trend = (m * row_number) + b 

और यहाँ मेरे (बहुत गंदा) एसक्यूएल कोड है::

SELECT resolved_half1,resolved_half2,opened_half1,opened_half2, c.period, 
((SUM (resolved_half1) OVER() + SUM(opened_half1) OVER()) - (SUM(resolved_half2) OVER() + SUM(opened_half2) OVER()))/((COUNT(resolved_half1) OVER() + COUNT(opened_half1) OVER())/2) as y1, 
((SUM(resolved_half2) OVER() + SUM(opened_half2) OVER())/(COUNT(resolved_half2) OVER() + COUNT (opened_half2) OVER())) as y2, 
((COUNT(c.period) OVER())/4) as x1, 
(((COUNT(c.period) OVER())/4) * 3) as x2, 
((CAST(((SUM (resolved_half1) OVER() + SUM(opened_half1) OVER()) - (SUM(resolved_half2) OVER() + SUM(opened_half2) OVER()))/((COUNT(resolved_half1) OVER() + COUNT(opened_half1) OVER())/2) as float) - CAST(((SUM(resolved_half2) OVER() + SUM(opened_half2) OVER())/(COUNT(resolved_half2) OVER() + COUNT (opened_half2) OVER())) as float))/(CAST(((COUNT(c.period) OVER())/4) as float) - CAST((((COUNT(c.period) OVER())/4) * 3) as float))) as m, 
(CAST(((SUM(resolved_half2) OVER() + SUM(opened_half2) OVER())/(COUNT(resolved_half2) OVER() + COUNT (opened_half2) OVER())) as float) - (((CAST(((SUM (resolved_half1) OVER() + SUM(opened_half1) OVER()) - (SUM(resolved_half2) OVER() + SUM(opened_half2) OVER()))/((COUNT(resolved_half1) OVER() + COUNT(opened_half1) OVER())/2) as float) - CAST(((SUM(resolved_half2) OVER() + SUM(opened_half2) OVER())/(COUNT(resolved_half2) OVER() + COUNT (opened_half2) OVER())) as float))/(CAST(((COUNT(c.period) OVER())/4) as float) - CAST((((COUNT(c.period) OVER())/4) * 3) as float))) * (((COUNT(c.period) OVER())/4) * 3))) as b, 
((((CAST(((SUM (resolved_half1) OVER() + SUM(opened_half1) OVER()) - (SUM(resolved_half2) OVER() + SUM(opened_half2) OVER()))/((COUNT(resolved_half1) OVER() + COUNT(opened_half1) OVER())/2) as float) - CAST(((SUM(resolved_half2) OVER() + SUM(opened_half2) OVER())/(COUNT(resolved_half2) OVER() + COUNT (opened_half2) OVER())) as float))/(CAST(((COUNT(c.period) OVER())/4) as float) - CAST((((COUNT(c.period) OVER())/4) * 3) as float))) * (ROW_NUMBER() OVER(ORDER BY c.yearClosed,c.weekClosed))) + (CAST(((SUM(resolved_half2) OVER() + SUM(opened_half2) OVER())/(COUNT(resolved_half2) OVER() + COUNT (opened_half2) OVER())) as float) - (((CAST(((SUM (resolved_half1) OVER() + SUM(opened_half1) OVER()) - (SUM(resolved_half2) OVER() + SUM(opened_half2) OVER()))/((COUNT(resolved_half1) OVER() + COUNT(opened_half1) OVER())/2) as float) - CAST(((SUM(resolved_half2) OVER() + SUM(opened_half2) OVER())/(COUNT(resolved_half2) OVER() + COUNT (opened_half2) OVER())) as float))/(CAST(((COUNT(c.period) OVER())/4) as float) - CAST((((COUNT(c.period) OVER())/4) * 3) as float))) * (((COUNT(c.period) OVER())/4) * 3)))) as trend, 
ROW_NUMBER() OVER(ORDER BY c.yearClosed,c.weekClosed) as row 

FROM 
    (SELECT *, CAST(yearClosed as varchar(5)) + ', ' + CAST(weekClosed as varchar(5)) AS period 
    FROM (SELECT  TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS resolved_half1, { fn WEEK(date_closed) } AS weekClosed, { fn YEAR(date_closed) } AS yearClosed 
          FROM   v_rpt_Service 
     WHERE (date_closed >= DateAdd(Day, DateDiff(Day, 0, GetDate()) - (180), 0)) 

     GROUP BY { fn WEEK(date_closed) }, { fn YEAR(date_closed) }) AS a 
     LEFT OUTER JOIN 
     (SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS opened_half1, { fn WEEK(date_entered) } AS weekEntered, { fn YEAR(date_entered) 
     FROM v_rpt_Service AS v_rpt_Service_1 
     WHERE (date_entered > = DateAdd(Day, DateDiff(Day, 0, GetDate()) - (180), 0)) 
     GROUP BY { fn WEEK(date_entered) }, { fn YEAR(date_entered) }) AS b ON a.weekClosed = b.weekEntered AND a.yearClosed = b.yearEntered) as c 
     LEFT OUTER JOIN 
     (SELECT *, CAST(yearClosed as varchar(5)) + ', ' + CAST(weekClosed as varchar(5)) AS period 
     FROM (SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS resolved_half2, { fn WEEK(date_closed) } AS weekClosed, { fn YEAR(date_closed) } AS yearClosed 
     FROM v_rpt_Service 
     WHERE (date_closed >= DateAdd(Day, DateDiff(Day, 0, GetDate()) - (180/2), 0)) 
     GROUP BY { fn WEEK(date_closed) }, { fn YEAR(date_closed) }) AS d 
     LEFT OUTER JOIN 
     (SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS opened_half2, { fn WEEK(date_entered) } AS weekEntered, { fn YEAR(date_entered)} AS yearEntered 
     FROM v_rpt_Service AS v_rpt_Service_1 
     WHERE (date_entered > = DateAdd(Day, DateDiff(Day, 0, GetDate()) - (180/2), 0)) 
     GROUP BY { fn WEEK(date_entered) }, { fn YEAR(date_entered) }) AS e ON d.weekClosed = e.weekEntered AND d.yearClosed = e.yearEntered 
) as f ON c.yearClosed = f.yearClosed AND c.weekClosed = f.weekClosed AND c.weekEntered = f.weekEntered AND c.yearEntered = f.yearEntered AND c.period = f.period 
GROUP BY c.period, resolved_half1,resolved_half2,opened_half1,opened_half2,c.yearClosed,c.weekClosed 
ORDER BY row 

इस कोड को 180 दिनों की एक हार्ड कोडित मान का उपयोग करता ये मेरी सूत्रों प्रत्येक मान प्राप्त करने के लिए कर रहे हैं। मुझे अभी भी दिनों की संख्या चुनने के लिए एक varibale का उपयोग करने में सक्षम होना चाहिए (0 त्रुटि से विभाजित किए बिना), और कोड को वास्तव में साफ करने की आवश्यकता है। यदि कोई मेरे लिए उन दो चीजें कर सकता है (मैं एसक्यूएल में सबसे अच्छा नहीं हूं), तो बक्षीस उनका है।

छवि:

Chart

0

मुझे विश्वास है कि इस चाल करना होगा - अगर कुछ वास्तविक नमूना डेटा पोस्ट नहीं है और मैं अगर मैं इसे ठीक करने के लिए परिवर्तित कर सकते हैं देखेंगे:

DECLARE @noOfDays INT 
SET @noofdays = 180 

;WITH tickets AS 
(
SELECT DISTINCT 
DATENAME(YEAR,date_closed) + RIGHT('000' + CAST(DATEPART(WEEK,date_closed) AS VARCHAR(5)),3) as Period 
,ticket_nbr 
,1 as ticket_type --resolved 
FROM v_rpt_Service 
WHERE (date_closed >= DateAdd(Day, DateDiff(Day, 0, GetDate()) - @NoOfDays, 0)) 
UNION ALL 
SELECT DISTINCT 
DATENAME(YEAR,date_closed) + RIGHT('000' + CAST(DATEPART(WEEK,date_closed) AS VARCHAR(5)),3) as Period 
,ticket_nbr 
,0 as ticket_type --opened 
FROM v_rpt_Service 
WHERE (date_entered > = DateAdd(Day, DateDiff(Day, 0, GetDate()) - @NoOfDays, 0)) 
) 
,tickets2 AS 
(
SELECT 
Period 
,SUM(CASE WHEN ticket_type = 0 THEN 1 ELSE 0 END) as opened 
,SUM(CASE WHEN ticket_type = 1 THEN 1 ELSE 0 END) as closed 
FROM tickets 
GROUP BY 
Period 
) 
,tickets3 AS 
(
SELECT 
Period 
,row_number() OVER (ORDER BY period ASC) as row 
,opened 
,closed 
,COUNT(period) OVER() as base 
,SUM(opened) OVER() as [Sumopened] 
,SUM(opened * opened) OVER() as [Sumopened^2] 
,SUM(opened * closed) OVER() as [Sumopenedclosed] 
,SUM(closed) OVER() as [Sumclosed] 
,SUM(closed * closed) OVER() as [Sumclosed^2] 
,SUM(opened * closed) OVER() * COUNT(period) OVER() AS [nSumopenedclosed] 
,SUM(opened) OVER() * SUM(closed) OVER() AS [Sumopened*Sumclosed] 
,SUM(opened * opened) OVER() * COUNT(period) OVER() AS [nSumopened^2] 
,SUM(opened) OVER() * SUM(opened) OVER() as [Sumopened*Sumopened] 
FROM tickets2 
) 
--Formula for linear regression is Y = A + BX 
SELECT 
period 
,opened 
,closed 
,((1.0/base) * [Sumclosed]) - 
([Sumopenedclosed] - ([Sumopened*Sumclosed]/base))/([Sumopened^2] - ([Sumopened*Sumopened]/base)) *((1.0/base) * [Sumopened]) 
+ row * ([Sumopenedclosed] - ([Sumopened*Sumclosed]/base))/([Sumopened^2] - ([Sumopened*Sumopened]/base)) 
AS trend_point 
,((1.0/base) * [Sumclosed]) - 
([Sumopenedclosed] - ([Sumopened*Sumclosed]/base))/([Sumopened^2] - ([Sumopened*Sumopened]/base)) *((1.0/base) * [Sumopened]) AS A 
,([Sumopenedclosed] - ([Sumopened*Sumclosed]/base))/([Sumopened^2] - ([Sumopened*Sumopened]/base)) as B 
from tickets3 
3

मैं इस समस्या में रुचि थी, और मैं ने पाया है कि एक जटिल क्वेरी grok का सबसे अच्छा तरीका मेरी खुद की शैली और परंपराओं का उपयोग कर उसे पुन: प्रारूपित है। मैंने उन्हें आपके समाधान पर लागू किया, और परिणाम नीचे है। मुझे पता नहीं है, तो यह आपके लिए कोई मूल्य होगा ...

  • ऐसे ({fn xxx } और WEEK(xxx) के रूप में कोड है कि मैं नहीं मानता कि एमएस टी SQL सिंटैक्स का हिस्सा हैं के कुछ बिट्स, थे समारोह।
  • इस कोड को संकलित करता है, लेकिन मैं इसे नहीं चल सकता क्योंकि मैं एक डेटा तालिका ठीक से विन्यस्त नहीं है।
  • मैं परिवर्तन है कि समझाने का एक गंभीर बहुत ले जाएगा कोडिंग के एक मेजबान बनाया है, और मुझे लगता है कि के सबसे छोड़ जा रहा हूँ। अगर आप कुछ भी खोजना चाहते हैं तो एक टिप्पणी जोड़ें।
  • मैं खाली स्थान के का एक बहुत में फेंक दिया। सुस्पष्ट और गैरकानूनी कोड के बीच का अंतर अक्सर दर्शक की धारणा और संवेदनशीलता होती है, और आप मेरे सम्मेलनों से नफरत कर सकते हैं।
  • सुनिश्चित नहीं हैं कि अंतिम परिणाम सेट होना चाहिए (यानी जो कॉलम लौटे हो)

कुछ आगे नोट:

  • इस क्वेरी आइटम एक सप्ताह में प्रवेश किया नहीं होगा अगर कोई आइटम भी थे उस सप्ताह में बंद
  • सप्ताह आंशिक हो सकते हैं, उदाहरण के लिए नहीं सातों दिन उपस्थित हो सकता है (@Interval समायोजित हमेशा पूर्ण सप्ताह जैसी - लेकिन क्या अजीब गिने अंतराल के बारे में) 1.0 से
  • गुणा गिनती (*) मान जल्दी तैरता के लिए उन्हें बदलने के लिए (से बचा जाता है कलाकारों और पूर्णांक गणित काट-छांट)
  • बनाया गया यह पहले सूत्रों बाद में सूत्रों में प्रतीकों द्वारा प्रतिस्थापित किया जा करने के लिए (जिस बिंदु पर बातें अधिक सुपाठ्य एक बहुत)

तो यहाँ बन अनुमति देने के लिए एक CTE क्या मैं के साथ आया है:

;WITH cte as (
select 
    c.period 
    ,resolved_half1 
    ,resolved_half2 
    ,opened_half1 
    ,opened_half2 
    ,row = row_number() over(order by c.yearClosed, c.weekClosed) 
    ,y1 = ((SUM(resolved_half1) + SUM(opened_half1)) - (SUM(resolved_half2) + SUM(opened_half2)))/((count(resolved_half1) + count(opened_half1))/2) 
    ,y2 = ((SUM(resolved_half2) + SUM(opened_half2))/(count(resolved_half2) + COUNT (opened_half2))) 
    ,x1 = ((count(c.period))/4) 
    ,x2 = (((count(c.period))/4) * 3) 
from (select 
      a.yearclosed 
     ,a.weekClosed 
     ,a.resolved_half1 
     ,b.yearEntered 
     ,b.weekEntered 
     ,b.opened_half1 
     ,cast(a.yearClosed as varchar(5)) + ', ' + cast(a.weekClosed as varchar(5)) period 
     from (-- Number of items per week that closed within @Interval 
       select 
       count(distinct TicketNbr) * 1.0 resolved_half1 
       ,datepart(wk, date_closed)  weekClosed 
       ,year(date_closed)    yearClosed 
       from v_rpt_Service 
       where date_closed >= @FullInterval 
       group by 
       datepart(wk, date_closed) 
       ,year(date_closed)) a 
     left outer join (-- Number of items per week that were entered within @Interval 
          select 
          count(distinct TicketNbr) * 1.0 opened_half1 
          ,datepart(wk, date_entered)  weekEntered 
          ,year(date_entered)    yearEntered 
          from v_rpt_Service 
          where date_entered >= @FullInterval 
          group by 
          datepart(wk, date_entered) 
          ,year(date_entered)) b 
      on a.weekClosed = b.weekEntered 
      and a.yearClosed = b.yearEntered) c 
    left outer join (select 
         d.yearclosed 
         ,d.weekClosed 
         ,d.resolved_half2 
         ,e.yearEntered 
         ,e.weekEntered 
         ,e.opened_half2 
         ,cast(yearClosed as varchar(5)) + ', ' + cast(weekClosed as varchar(5)) period 
        from (select 
          count(distinct TicketNbr) * 1.0 resolved_half2 
          ,datepart(wk, date_closed)  weekClosed 
          ,year(date_closed)    yearClosed 
          from v_rpt_Service 
          where date_closed >= @HalfInterval 
          group by 
          datepart(wk, date_closed) 
          ,year(date_closed)) d 
        left outer join (select 
             count(distinct TicketNbr) * 1.0 opened_half2 
             ,datepart(wk, date_entered)  weekEntered 
             ,year(date_entered)    yearEntered 
             from v_rpt_Service 
             where date_entered >= @HalfInterval 
             group by 
              datepart(wk, date_entered) 
              ,year(date_entered)) e 
         on d.weekClosed = e.weekEntered 
         and d.yearClosed = e.yearEntered) f 
    on c.period = f.period 
group by 
    c.period 
    ,resolved_half1 
    ,resolved_half2 
    ,opened_half1 
    ,opened_half2 
    ,c.yearClosed 
    ,c.weekClosed 
) 
SELECT 
    row 
    ,Period 
    ,x1 
    ,y1 
    ,x2 
    ,y2 
    ,m = ((y1 - y2)/(x1 - x2)) 
    ,b = (y2 - (((y1 - y2)/(x1 - x2)) * x2)) 
    ,trend = ((((y1 - y2)/(x1 - x2)) * (row)) + (y2 - (((y1 - y2)/(x1 - x2)) * x2))) 
from cte 
order by row 

एक परिशिष्ट के रूप में, सबक्वेरी के सभी "सी" सह उल कुछ को निम्न तरह से बदल दिया गया है, और "एफ" थोड़ा संशोधित संस्करण के साथ बदला जा सकता है। बेहतर या खराब प्रदर्शन टेबल आकार, अनुक्रमण, और अन्य imponderables पर निर्भर करता है।

select 
    datepart(wk, date_closed) weekClosed 
    ,year(date_closed)   yearClosed 
    ,count (distinct case 
        when date_closed >= @FullInterval then TicketNbr 
        else null 
       end)   resolved_half1 
    ,count (distinct case 
        when date_entered >= @FullInterval then TicketNbr 
        else null 
       end)   opened_half1 
from v_rpt_Service 
where date_closed >= @FullInterval 
    or date_entered >= @FullInterval 
group by 
    datepart(wk, date_closed) 
    ,year(date_closed) 
संबंधित मुद्दे