समूह के लिए पिछली आबादी की तारीख से डेटा मूल्य के साथ लापता तिथियों को भरें


13

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

CREATE TABLE TicketAssigment (
    TicketId     INT NOT NULL,
    AssignedDate DATE NOT NULL,
    DepartmentId INT NOT NULL);

मुझे प्रत्येक TicketId के लिए किसी भी लापता तिथियों को भरने की आवश्यकता है, तिथि द्वारा आदेशित पिछले TicketAssigment पंक्ति से विभाग का उपयोग करके।

अगर मेरे पास इस तरह TicketAssigment पंक्तियाँ हैं:

1, '1/1/2016', 123 -- Opened
1, '1,4,2016', 456 -- Transferred and closed
2, '1/1/2016', 25  -- Opened
2, '1/2/2016', 52  -- Transferred
2, '1/4/2016', 25  -- Transferred and closed

मुझे यह आउटपुट चाहिए:

1, '1/1/2016', 123
1, '1/2/2016', 123
1, '1/3/2016', 123
1, '1/4/2016', 456
2, '1/1/2016', 25
2, '1/2/2016', 52
2, '1/3/2016', 52
2, '1/4/2016', 25

ऐसा लगता है कि यह मेरी ज़रूरत के करीब हो सकता है, लेकिन मुझे इसे खत्म करने का धैर्य नहीं था, और अनुमानित योजना लागत में 6 अंक हैं:

SELECT  l.TicketId, c.Date, MIN(l.DepartmentId)
FROM    dbo.Calendar c 
        OUTER APPLY (SELECT TOP 1 TicketId, DepartmentId FROM TicketAssigment WHERE AssignedDate <= c.Date ORDER BY AssignedDate DESC) l
WHERE   c.Date <= (SELECT MAX(AssignedDate) FROM TicketAssigment)
GROUP   BY l.TicketId, c.Date
ORDER   BY l.TicketId, c.Date;

मुझे संदेह है कि एलएजी और एक खिड़की के फ्रेम का उपयोग करने का एक तरीका है, लेकिन मुझे यह पता नहीं चला है। आवश्यकता को पूरा करने का एक अधिक कुशल तरीका क्या है?

जवाबों:


14

LEAD()TicketId विभाजन के भीतर अगली पंक्ति प्राप्त करने के लिए उपयोग करें । फिर सभी तिथियों को प्राप्त करने के लिए एक कैलेंडर तालिका में शामिल हों।

WITH TAwithnext AS
(SELECT *, LEAD(AssignmentDate) OVER (PARTITION BY TicketID ORDER BY AssignmentDate) AS NextAssignmentDate
 FROM TicketAssignment
)
SELECT t.TicketID, c.Date, t.DepartmentID
FROM dbo.Calendar c
JOIN TAwithnext t
    ON c.Date BETWEEN t.AssignmentDate AND ISNULL(DATEADD(day,-1,t.NextAssignmentDate),t.AssignmentDate)
;

कैलेंडर तालिका प्राप्त करने के सभी प्रकार ...


4

यह करने का एक त्वरित तरीका है (मैंने प्रदर्शन या स्केलबेलिटी के लिए परीक्षण नहीं किया है)

- कैलेंडर तालिका बनाएं

-- borrowed from @Aaron's post http://sqlperformance.com/2013/01/t-sql-queries/generate-a-set-3 
CREATE TABLE dbo.Calendar(d DATE PRIMARY KEY);

INSERT dbo.Calendar(d) SELECT TOP (365)
 DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, '20160101')
 FROM [master].dbo.spt_values
 WHERE [type] = N'P' ORDER BY number;

--- अपनी परीक्षा तालिका बनाएं

CREATE TABLE dbo.TicketAssigment (
    TicketId     INT NOT NULL,
    AssignedDate DATE NOT NULL,
    DepartmentId INT NOT NULL);

--  truncate table dbo.TicketAssigment;

insert into dbo.TicketAssigment values (1   ,   '1-1-2016'  ,   123 )
insert into dbo.TicketAssigment values (1   ,   '1-4-2016'  ,   456 )
insert into dbo.TicketAssigment values (2   ,   '1-1-2016'  ,   25  )
insert into dbo.TicketAssigment values (2   ,   '1-2-2016'  ,   52  )
insert into dbo.TicketAssigment values (2   ,   '1-4-2016'  ,   25  )

--- वांछित आउटपुट प्राप्त करने की क्वेरी

;with Cte as
(
  select TicketID, 
         min(AssignedDate) minAD, -- This is the min date
         max(AssignedDate) maxAD  -- This is the max date
  from TicketAssigment
  group by TicketID
)
select Cte.TicketID,
       c.d as AssignedDate,

       ( -- Get DeptID
       select top(1) T.departmentID
       from dbo.TicketAssigment as T
       where T.TicketID = cte.TicketID and
             T.AssignedDate <= c.d
       order by T.AssignedDate desc
       ) as DepartmentID
from Cte
  left outer join dbo.Calendar as c
      on c.d between Cte.minAD and Cte.maxAD
    order by Cte.TicketID

यहाँ छवि विवरण दर्ज करें


इसके लिए धन्यवाद! अनुमानित निष्पादन योजना 25 बिलियन पंक्तियों का एक परिणाम सेट दिखाती है, इसलिए हम रिपोर्टिंग आवश्यकता (जो वर्तमान में पिछले वर्ष के लिए प्रत्येक टिकट के लिए हर दिन रिपोर्ट करना चाहते हैं) पर फिर से विचार करने जा रहे हैं। मुझे उम्मीद है कि हम प्रत्येक टिकट के लिए अंतिम डिपार्टमेंटआईड दिखा सकते हैं और अनुरोध पर एकल चयनित टिकट के लिए दिन-प्रतिदिन डिपार्टमेंटआईड का विवरण दिखा सकते हैं।
मार्क फ्रीमैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.