Advertisement
stegus64

sqlugchallenge 2017

Mar 24th, 2017
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 2.91 KB | None | 0 0
  1. /*
  2. Stefan Gustafsson Acando
  3.  
  4. opt1
  5.  
  6. Process one month at a time, optimized
  7. */
  8.  
  9. set nocount on
  10.  
  11. truncate table dbo.Customers
  12.  
  13. declare @t0 datetime = getdate()
  14. declare @ms int
  15.  
  16. -- Calculate the range of months to process
  17. declare @firstdate date = (select top 1 date from dbo.Purchases order by PurchaseID asc)
  18. declare @lastdate  date = (select top 1 date from dbo.Purchases order by PurchaseID desc)
  19. declare @lastmonth int = datediff(month, @firstdate, @lastdate)
  20. RAISERROR ('@lastmonth: %d',0,0,@lastmonth) WITH NOWAIT
  21.  
  22. -- Create temp table for edges
  23. IF object_id('tempdb..#e') IS NOT NULL DROP TABLE #e
  24. create table #e       (MonthNumber int not null, node_s int not null, node_t int not null)
  25. -- disable statistics generation
  26. create statistics e1 on #e(MonthNumber) with norecompute
  27. create statistics e2 on #e(node_s) with norecompute
  28. create statistics e3 on #e(node_t) with norecompute
  29.  
  30. -- Build edge list
  31. ;with
  32. p as (
  33.     select PurchaseID, DATEDIFF(month, @firstdate, date) as MonthNumber, FirstName, LastName, Email, StreetAddress, ZipCode, CreditCard
  34.     from dbo.Purchases
  35. )
  36. , cte1a as (
  37.     select
  38.         PurchaseID,
  39.         MonthNumber,
  40.         Key1 = (Firstname+'/'+CreditCard) collate finnish_swedish_bin,
  41.         Key2 = (Firstname+'/'+Email) collate finnish_swedish_bin,
  42.         Key3 = (Firstname+'/'+LastName+'/'+StreetAddress+'/'+cast(ZipCode as varchar(10))) collate finnish_swedish_bin
  43.     from p
  44. )
  45. , k1 as (
  46.     select Key1, MIN(PurchaseID) as node
  47.     from cte1a
  48.     group by Key1
  49. )
  50. , k2 as (
  51.     select Key2, MIN(PurchaseID) as node
  52.     from cte1a
  53.     group by Key2
  54. )
  55. , k3 as (
  56.     select Key3, MIN(PurchaseID)as node
  57.     from cte1a
  58.     group by Key3
  59. )
  60. ,cte2 as (
  61.     select
  62.         a.PurchaseID,
  63.         a.MonthNumber,
  64.         k1.node as n1,
  65.         k2.node as n2,
  66.         k3.node as n3
  67.     from cte1a a
  68.     join k1 on k1.Key1 = a.Key1
  69.     join k2 on k2.Key2 = a.Key2
  70.     join k3 on k3.Key3 = a.Key3
  71. )
  72. , cte3 as (
  73.     select *,
  74.         -- Set node_t to min(n1,n2,n3)
  75.         node_t = case
  76.             when n1 < n2 then
  77.                 case when n1 < n3 then n1 else n3 end
  78.             else
  79.                 case when n2 < n3 then n2 else n3 end
  80.             end
  81.     from cte2
  82. )
  83. insert into #e
  84. select
  85.     MonthNumber,
  86.     node_s = PurchaseID,
  87.     node_t
  88. from cte3
  89.  
  90. set @ms = datediff(ms, @t0, GETDATE())
  91. RAISERROR ('#e duration: %d ms',0,0,@ms) WITH NOWAIT
  92.  
  93. -- Process edge list one month at a time
  94. begin tran
  95. declare @i int = 0
  96. while @i <= @lastmonth
  97. begin
  98.  
  99.     insert into dbo.Customers (PurchaseID, CustomerID)
  100.     select node_s, ISNULL(b.CustomerID, a.node_t)
  101.     from #e a
  102.     left join dbo.Customers b with (forceseek)
  103.         on b.PurchaseID = a.node_t
  104.     where a.MonthNumber = @i
  105.     option (keepfixed plan)
  106.  
  107.     set @i = @i+1
  108.  
  109. end
  110. commit
  111.  
  112. set @ms = datediff(ms, @t0, GETDATE())
  113. RAISERROR ('duration: %d ms',0,0,@ms) WITH NOWAIT
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement