Isi tanggal yang hilang dengan nilai data dari tanggal populasi sebelumnya untuk grup


13

Gambar tiket help desk yang ditransfer antar departemen. Kami ingin tahu apa departemen pada akhir hari untuk setiap tiket untuk setiap hari tiket dibuka. Tabel berisi departemen terakhir untuk setiap tiket untuk setiap hari tiket terbuka di mana ada perubahan di departemen (termasuk baris untuk tanggal tiket awalnya dibuka dan tanggal penutupan). Tabel data terlihat seperti ini:

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

Yang saya butuhkan adalah mengisi tanggal yang hilang untuk setiap TicketId, menggunakan DepartmentId dari baris TicketAssigment sebelumnya yang dipesan berdasarkan Tanggal.

Jika saya memiliki baris TicketAssigment seperti ini:

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

Saya ingin hasil ini:

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

Ini sepertinya dekat dengan yang saya butuhkan, tetapi saya belum memiliki kesabaran untuk menyelesaikannya, dan perkiraan biaya rencana memiliki 6 digit:

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;

Saya curiga ada cara untuk melakukan ini menggunakan LAG dan bingkai jendela, tapi saya belum mengetahuinya. Apa cara yang lebih efisien untuk memenuhi persyaratan?

Jawaban:


14

Gunakan LEAD()untuk mendapatkan baris berikutnya dalam partisi TicketId. Kemudian gabung ke tabel Kalender untuk mendapatkan semua tanggal.

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)
;

Segala macam cara untuk mendapatkan tabel Kalender ...


4

Ini adalah cara cepat untuk melakukan (Saya belum menguji kinerja atau skalabilitas)

- buat tabel Kalender

-- 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;

--- buat tabel tes Anda

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  )

--- Permintaan untuk mendapatkan output yang diinginkan

;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

masukkan deskripsi gambar di sini


Terima kasih untuk ini! Perkiraan rencana eksekusi menunjukkan serangkaian hasil 25 miliar baris, jadi kami akan menegosiasikan ulang persyaratan pelaporan (yang saat ini akan melaporkan setiap hari untuk setiap tiket selama setahun terakhir). Saya berharap kami dapat menunjukkan DepartmentId terakhir untuk setiap tiket dan menunjukkan detail DepartmentId per hari untuk satu tiket yang dipilih berdasarkan permintaan.
Mark Freeman
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.