Advertisement
Karfunkel

Nitzachon

Mar 19th, 2017
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 30.68 KB | None | 0 0
  1. /*
  2. Denna lösning ger varje kund ett CustomerID som är kundens lägsta PurchaseID.
  3. Det går att vinna pyttelite tid på att inte välja lägsta PurchaseID,
  4. men den lilla tidsförlusten bjuder jag på i estetikens namn.
  5.  
  6. Vi har tre ekvivalensregler:
  7. - FirstName + CreditCard
  8. - FirstName + Email
  9. - FirstName + LastName + StreetAddress + ZipCode
  10.  
  11. Lösningen består av tre huvudsteg:
  12. 1) Varje kombination i varje ekvivalensregel tilldelas ett tal som är det lägsta PurchaseID där kombinationen förekommer.
  13. 2) I tabellen Rules läggs alla PurchaseID och deras tre värden från föregående steg.
  14. 3) I tabellen Clusters kopplas sedan de olika värdena från Steg 1 samman via förekomst på samma rad i Rules.
  15.  
  16. Mer kommentarer i koden.
  17. */
  18. SET NOCOUNT ON;
  19. -- DROP
  20. -- Tables
  21. IF OBJECT_ID('dbo.Rules', 'U') IS NOT NULL
  22. DROP TABLE dbo.Rules;
  23. IF OBJECT_ID('dbo.Clusters', 'U') IS NOT NULL
  24. DROP TABLE dbo.Clusters;
  25. TRUNCATE TABLE dbo.Customers;
  26.  
  27. -- Cursor
  28. IF CURSOR_STATUS('global','outer_cursor') >= -1
  29. DEALLOCATE outer_cursor;
  30.  
  31. -- CREATE
  32. -- Tables
  33. CREATE TABLE dbo.Rules (
  34.     PurchaseID int NOT NULL
  35.    ,ClusterR1 int NOT NULL
  36.    ,ClusterR2 int NOT NULL
  37.    ,ClusterR3 int NOT NULL
  38. );
  39.  
  40. CREATE TABLE dbo.Clusters (
  41.     ClusterID int NOT NULL PRIMARY KEY
  42.    ,ClusterOnRow int NOT NULL
  43.    ,Cluster varchar(MAX) NOT NULL
  44. );
  45.  
  46. /*
  47. I mina tidigare lösningar lade jag tre ickeklustrade index på Purchases, ett för varje ekvivalensregel.
  48. Eftersom uppslag bara sker på dessa kolumner i det inledande steget (GROUP BY), har dessa index slopats.
  49. */
  50.  
  51. -- STEG 1-2
  52. WITH Rule1 AS (
  53. SELECT
  54.     MIN(PurchaseID) AS Cluster
  55.    ,FirstName
  56.    ,CreditCard
  57. FROM dbo.Purchases
  58. GROUP BY FirstName, CreditCard
  59. )
  60. , Rule2 AS (
  61. SELECT
  62.     MIN(PurchaseID) AS Cluster
  63.    ,FirstName
  64.    ,Email
  65. FROM dbo.Purchases
  66. GROUP BY FirstName, Email
  67. )
  68. , Rule3 AS (
  69. SELECT
  70.     MIN(PurchaseID) AS Cluster
  71.    ,FirstName
  72.    ,LastName
  73.    ,StreetAddress
  74.    ,ZipCode
  75. FROM dbo.Purchases
  76. GROUP BY FirstName, LastName, StreetAddress, ZipCode
  77. )
  78. INSERT INTO dbo.Rules
  79. WITH (TABLOCK)
  80. SELECT
  81.     p.PurchaseID
  82.    ,r1.Cluster AS ClusterR1
  83.    ,r2.Cluster AS ClusterR2
  84.    ,r3.Cluster AS ClusterR3
  85. FROM dbo.Purchases AS p
  86. JOIN Rule1 AS r1 ON r1.FirstName = p.FirstName AND r1.CreditCard = p.CreditCard
  87. JOIN Rule2 AS r2 ON r2.FirstName = p.FirstName AND r2.Email = p.Email
  88. JOIN Rule3 AS r3 ON r3.FirstName = p.FirstName AND r3.LastName = p.LastName AND r3.StreetAddress = p.StreetAddress AND r3.ZipCode = p.ZipCode;
  89.  
  90. DECLARE @maxid int;
  91. SELECT @maxid = MAX(PurchaseID) FROM dbo.Purchases;
  92. DECLARE @itemlength int;
  93. SELECT @itemlength = LEN(CAST(@maxid AS varchar));
  94. DECLARE @cl1 int;
  95. DECLARE @cl2 int;
  96. DECLARE @cl3 int;
  97. DECLARE @clusterOnRow1 int;
  98. DECLARE @clusterOnRow2 int;
  99. DECLARE @cluster1 varchar(MAX);
  100. DECLARE @cluster2 varchar(MAX);
  101. DECLARE @cluster3 varchar(MAX);
  102. DECLARE @cluster4 varchar(MAX);
  103. DECLARE @i int;
  104.  
  105. -- STEG 3
  106. /*
  107. Detta är den huvudsakliga algoritmen, som kopplar ihop kombinationer från de olika
  108. ekvivalensreglerna med varandra.
  109.  
  110. Jag betraktar detta som ett grafproblem. Varje unikt värde (PurchaseID) som genererats
  111. i STEG 1 är en nod. När detta steg inleds finns inga kanter.
  112. Detta steg kommer sedan loopa igenom alla unika kombinationer från tabellen Rules. De
  113. motsvarande noderna kommer kopplas ihop med kanter, så att hopkopplade noder anses
  114. motsvara samma kund.
  115.  
  116. Hopkopplingen av noder sker på ett bestämt vis. De bildar alltid träd med maxdjup 1 (stjärnor),
  117. där en nod är rot, och alla andra är löv. Detta åstadkoms med hjälp av tabellen Clusters.
  118.  
  119. Clusters innehåller en rad för varje startnod (unikt PurchaseID från STEG 1). Förutom
  120. nyckelkolumnen ClusterID (int) finns kolumnen ClusterOnRow (int) som pekar på den rad i
  121. samma tabell som är rot i det träd där raden ingår. Från början är ClusterOnRow = ClusterID.
  122. Sist finns kolumnen Cluster, som är en s.k. Adjacency List i form av en varchar(MAX).
  123. Kolumnen Cluster är bara intressant på de rader där ClusterOnRow = ClusterID, vilket är
  124. rotnoderna. Den innehåller en konkatenering av samtliga noder i trädet, med det lägsta
  125. numret först. Om det högsta förekommande PurchaseID är sexsiffrigt kommer alla noder
  126. motsvaras av en varchar(6). Klustret 3-4497-98 blir då '000003004497000098'.
  127. */
  128.  
  129. WITH IDS AS (
  130. SELECT DISTINCT ClusterR1 AS ClusterID FROM dbo.Rules
  131. UNION
  132. SELECT DISTINCT ClusterR2 AS ClusterID FROM dbo.Rules
  133. UNION
  134. SELECT DISTINCT ClusterR3 AS ClusterID FROM dbo.Rules
  135. )
  136. INSERT INTO dbo.Clusters
  137. WITH (TABLOCK)
  138. SELECT
  139.     ClusterID    = ClusterID
  140.    ,ClusterOnRow = ClusterID
  141.    ,Cluster      = FORMAT(ClusterID, 'd' + CAST(@itemlength AS varchar))
  142. FROM IDS;
  143.  
  144. DECLARE outer_cursor CURSOR FOR
  145. SELECT DISTINCT
  146.     ClusterR1
  147.    ,ClusterR2
  148.    ,ClusterR3
  149. FROM dbo.Rules;
  150.  
  151. OPEN outer_cursor;
  152.  
  153. FETCH NEXT FROM outer_cursor
  154. INTO @cl1, @cl2, @cl3;
  155.  
  156. /*
  157. I koden nedan görs skillnad på tre typer av noder:
  158. * Eget kluster - noden är ensam.
  159. * Rotnod - har lövnoder under sig.
  160. * Lövnod - har en rotnod över sig.
  161. Av dessa tre nodtyper uppkommer sex olika kombinationer som måste tas hänsyn till:
  162. A) Två egna kluster
  163. B) Eget kluster + rotnod
  164. C) Eget kluster + lövnod
  165. D) Två rotnoder
  166. E) Rotnod + lövnod
  167. F) Två lövnoder
  168. */
  169. WHILE @@FETCH_STATUS = 0
  170. BEGIN
  171.  
  172.     IF @cl1 <> @cl2
  173.     BEGIN
  174.         SELECT
  175.             @clusterOnRow1 = ClusterOnRow
  176.            ,@cluster1      = Cluster
  177.         FROM dbo.Clusters
  178.         WHERE ClusterID = @cl1;
  179.        
  180.         SELECT
  181.             @clusterOnRow2 = ClusterOnRow
  182.            ,@cluster2      = Cluster
  183.         FROM dbo.Clusters
  184.         WHERE ClusterID = @cl2;
  185.        
  186.         IF @clusterOnRow1 <> @clusterOnRow2
  187.         BEGIN
  188.             IF @clusterOnRow1 = @cl1 -- A B C D E
  189.             BEGIN
  190.                 IF @clusterOnRow2 = @cl2 -- A B D
  191.                 BEGIN
  192.                     IF LEN(@cluster1) = @itemlength -- A B
  193.                     BEGIN
  194.                         UPDATE dbo.Clusters
  195.                         SET ClusterOnRow = @cl2
  196.                         WHERE ClusterID = @cl1;
  197.  
  198.                         UPDATE dbo.Clusters
  199.                         SET Cluster = CASE
  200.                                           WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster2, @itemlength) THEN @cluster1 + @cluster2
  201.                                           ELSE @cluster2 + @cluster1
  202.                                       END
  203.                         WHERE ClusterID = @cl2;
  204.                     END -- A B
  205.                     ELSE -- B D
  206.                     BEGIN
  207.                         IF LEN(@cluster2) = @itemlength -- B
  208.                         BEGIN
  209.                             UPDATE dbo.Clusters
  210.                             SET ClusterOnRow = @cl1
  211.                             WHERE ClusterID = @cl2;
  212.  
  213.                             UPDATE dbo.Clusters
  214.                             SET Cluster = CASE
  215.                                               WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster2, @itemlength) THEN @cluster1 + @cluster2
  216.                                               ELSE @cluster2 + @cluster1
  217.                                           END
  218.                             WHERE ClusterID = @cl1;
  219.                         END -- B
  220.                         ELSE -- D
  221.                         BEGIN
  222.                             SET @i = 1;
  223.                             IF LEN(@cluster1) <= LEN(@cluster2)
  224.                             BEGIN
  225.                                 WHILE @i * @itemlength <= LEN(@cluster1)
  226.                                 BEGIN
  227.                                     UPDATE dbo.Clusters
  228.                                     SET ClusterOnRow = @cl2
  229.                                     WHERE ClusterID = CAST(SUBSTRING(@cluster1,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  230.                                
  231.                                     SET @i = @i + 1;
  232.                                 END
  233.                                 UPDATE dbo.Clusters
  234.                                 SET Cluster = CASE
  235.                                                   WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster2, @itemlength) THEN @cluster1 + @cluster2
  236.                                                   ELSE @cluster2 + @cluster1
  237.                                               END
  238.                                 WHERE ClusterID = @cl2;
  239.                             END
  240.                             ELSE
  241.                             BEGIN
  242.                                 WHILE @i * @itemlength <= LEN(@cluster2)
  243.                                 BEGIN
  244.                                     UPDATE dbo.Clusters
  245.                                     SET ClusterOnRow = @cl1
  246.                                     WHERE ClusterID = CAST(SUBSTRING(@cluster2,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  247.                                
  248.                                     SET @i = @i + 1;
  249.                                 END
  250.                                 UPDATE dbo.Clusters
  251.                                 SET Cluster = CASE
  252.                                                   WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster2, @itemlength) THEN @cluster1 + @cluster2
  253.                                                   ELSE @cluster2 + @cluster1
  254.                                               END
  255.                                 WHERE ClusterID = @cl1;
  256.                             END
  257.                         END -- D
  258.                     END -- B D
  259.                 END -- A B D
  260.                 ELSE -- C E
  261.                 BEGIN
  262.                     IF LEN(@cluster1) = @itemlength -- C
  263.                     BEGIN
  264.                         UPDATE dbo.Clusters
  265.                         SET ClusterOnRow = @clusterOnRow2
  266.                         WHERE ClusterID = @cl1;
  267.  
  268.                         SELECT @cluster3 = Cluster
  269.                         FROM dbo.Clusters
  270.                         WHERE ClusterID = @clusterOnRow2;
  271.  
  272.                         UPDATE dbo.Clusters
  273.                         SET Cluster = CASE
  274.                                           WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster1 + @cluster3
  275.                                           ELSE @cluster3 + @cluster1
  276.                                       END
  277.                         WHERE ClusterID = @clusterOnRow2;
  278.                     END -- C
  279.                     ELSE -- E
  280.                     BEGIN
  281.                         SET @i = 1;
  282.  
  283.                         SELECT @cluster3 = Cluster
  284.                         FROM dbo.Clusters
  285.                         WHERE ClusterID = @clusterOnRow2;
  286.  
  287.                         IF LEN(@cluster1) <= LEN(@cluster3)
  288.                         BEGIN
  289.                             WHILE @i * @itemlength <= LEN(@cluster1)
  290.                             BEGIN
  291.                                 UPDATE dbo.Clusters
  292.                                 SET ClusterOnRow = @clusterOnRow2
  293.                                 WHERE ClusterID = CAST(SUBSTRING(@cluster1,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  294.  
  295.                                 SET @i = @i + 1;
  296.                             END
  297.  
  298.                             UPDATE dbo.Clusters
  299.                             SET Cluster = CASE
  300.                                               WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster1 + @cluster3
  301.                                               ELSE @cluster3 + @cluster1
  302.                                           END
  303.                             WHERE ClusterID = @clusterOnRow2;
  304.                         END
  305.                         ELSE
  306.                         BEGIN
  307.                             WHILE @i * @itemlength <= LEN(@cluster3)
  308.                             BEGIN
  309.                                 UPDATE dbo.Clusters
  310.                                 SET ClusterOnRow = @cl1
  311.                                 WHERE ClusterID = CAST(SUBSTRING(@cluster3,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  312.  
  313.                                 SET @i = @i + 1;
  314.                             END
  315.  
  316.                             UPDATE dbo.Clusters
  317.                             SET Cluster = CASE
  318.                                               WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster1 + @cluster3
  319.                                               ELSE @cluster3 + @cluster1
  320.                                           END
  321.                             WHERE ClusterID = @cl1;
  322.                         END
  323.                     END -- E
  324.                 END -- C E
  325.             END -- A B C D E
  326.             ELSE -- C E F
  327.             BEGIN
  328.                 IF @clusterOnRow2 = @cl2 -- C E
  329.                 BEGIN
  330.                     IF LEN(@cluster2) = @itemlength -- C
  331.                     BEGIN
  332.                         UPDATE dbo.Clusters
  333.                         SET ClusterOnRow = @clusterOnRow1
  334.                         WHERE ClusterID = @cl2;
  335.  
  336.                         SELECT @cluster3 = Cluster
  337.                         FROM dbo.Clusters
  338.                         WHERE ClusterID = @clusterOnRow1;
  339.  
  340.                         UPDATE dbo.Clusters
  341.                         SET Cluster = CASE
  342.                                           WHEN LEFT(@cluster2, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster2 + @cluster3
  343.                                           ELSE @cluster3 + @cluster2
  344.                                       END
  345.                         WHERE ClusterID = @clusterOnRow1;
  346.                     END -- C
  347.                     ELSE -- E
  348.                     BEGIN
  349.                         SET @i = 1;
  350.  
  351.                         SELECT @cluster3 = Cluster
  352.                         FROM dbo.Clusters
  353.                         WHERE ClusterID = @clusterOnRow1;
  354.  
  355.                         IF LEN(@cluster2) <= LEN(@cluster3)
  356.                         BEGIN
  357.                             WHILE @i * @itemlength <= LEN(@cluster2)
  358.                             BEGIN
  359.                                 UPDATE dbo.Clusters
  360.                                 SET ClusterOnRow = @clusterOnRow1
  361.                                 WHERE ClusterID = CAST(SUBSTRING(@cluster2,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  362.  
  363.                                 SET @i = @i + 1;
  364.                             END
  365.  
  366.                             UPDATE dbo.Clusters
  367.                             SET Cluster = CASE
  368.                                               WHEN LEFT(@cluster2, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster2 + @cluster3
  369.                                               ELSE @cluster3 + @cluster2
  370.                                           END
  371.                             WHERE ClusterID = @clusterOnRow1;
  372.                         END
  373.                         ELSE
  374.                         BEGIN
  375.                             WHILE @i * @itemlength <= LEN(@cluster3)
  376.                             BEGIN
  377.                                 UPDATE dbo.Clusters
  378.                                 SET ClusterOnRow = @cl2
  379.                                 WHERE ClusterID = CAST(SUBSTRING(@cluster3,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  380.  
  381.                                 SET @i = @i + 1;
  382.                             END
  383.  
  384.                             UPDATE dbo.Clusters
  385.                             SET Cluster = CASE
  386.                                               WHEN LEFT(@cluster2, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster2 + @cluster3
  387.                                               ELSE @cluster3 + @cluster2
  388.                                           END
  389.                             WHERE ClusterID = @cl2;
  390.                         END
  391.                     END -- E
  392.                 END  -- C E
  393.                 ELSE -- F
  394.                 BEGIN
  395.                     SELECT @cluster3 = Cluster
  396.                     FROM dbo.Clusters
  397.                     WHERE ClusterID = @clusterOnRow1;
  398.                    
  399.                     SELECT @cluster4 = Cluster
  400.                     FROM dbo.Clusters
  401.                     WHERE ClusterID = @clusterOnRow2;
  402.  
  403.                     SET @i = 1;
  404.                     IF LEN(@cluster3) <= LEN(@cluster4)
  405.                     BEGIN
  406.                         WHILE @i * @itemlength <= LEN(@cluster3)
  407.                         BEGIN
  408.                             UPDATE dbo.Clusters
  409.                             SET ClusterOnRow = @clusterOnRow2
  410.                             WHERE ClusterID = CAST(SUBSTRING(@cluster3,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  411.  
  412.                             SET @i = @i + 1;
  413.                         END
  414.                         UPDATE dbo.Clusters
  415.                         SET Cluster = CASE
  416.                                           WHEN LEFT(@cluster3, @itemlength) < LEFT (@cluster4, @itemlength) THEN @cluster3 + @cluster4
  417.                                           ELSE @cluster4 + @cluster3
  418.                                       END
  419.                         WHERE ClusterID = @clusterOnRow2;
  420.                     END
  421.                     ELSE
  422.                     BEGIN
  423.                         WHILE @i * @itemlength <= LEN(@cluster4)
  424.                         BEGIN
  425.                             UPDATE dbo.Clusters
  426.                             SET ClusterOnRow = @clusterOnRow1
  427.                             WHERE ClusterID = CAST(SUBSTRING(@cluster4,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  428.  
  429.                             SET @i = @i + 1;
  430.                         END
  431.                         UPDATE dbo.Clusters
  432.                         SET Cluster = CASE
  433.                                           WHEN LEFT(@cluster3, @itemlength) < LEFT (@cluster4, @itemlength) THEN @cluster3 + @cluster4
  434.                                           ELSE @cluster4 + @cluster3
  435.                                       END
  436.                         WHERE ClusterID = @clusterOnRow1;
  437.                     END
  438.                 END -- F
  439.             END -- C E F
  440.         END
  441.     END
  442.  
  443.     IF @cl1 <> @cl3 AND @cl2 <> @cl3
  444.     BEGIN
  445.         SELECT
  446.             @clusterOnRow1 = ClusterOnRow
  447.            ,@cluster1      = Cluster
  448.         FROM dbo.Clusters
  449.         WHERE ClusterID = @cl1;
  450.        
  451.         SELECT
  452.             @clusterOnRow2 = ClusterOnRow
  453.            ,@cluster2      = Cluster
  454.         FROM dbo.Clusters
  455.         WHERE ClusterID = @cl3;
  456.  
  457.         IF @clusterOnRow1 <> @clusterOnRow2
  458.         BEGIN
  459.             IF @clusterOnRow1 = @cl1 -- A B C D E
  460.             BEGIN
  461.                 IF @clusterOnRow2 = @cl3 -- A B D
  462.                 BEGIN
  463.                     IF LEN(@cluster1) = @itemlength -- A B
  464.                     BEGIN
  465.                         UPDATE dbo.Clusters
  466.                         SET ClusterOnRow = @cl3
  467.                         WHERE ClusterID = @cl1;
  468.  
  469.                         UPDATE dbo.Clusters
  470.                         SET Cluster = CASE
  471.                                           WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster2, @itemlength) THEN @cluster1 + @cluster2
  472.                                           ELSE @cluster2 + @cluster1
  473.                                       END
  474.                         WHERE ClusterID = @cl3;
  475.                     END -- A B
  476.                     ELSE -- B D
  477.                     BEGIN
  478.                         IF LEN(@cluster2) = @itemlength -- B
  479.                         BEGIN
  480.                             UPDATE dbo.Clusters
  481.                             SET ClusterOnRow = @cl1
  482.                             WHERE ClusterID = @cl3;
  483.  
  484.                             UPDATE dbo.Clusters
  485.                             SET Cluster = CASE
  486.                                               WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster2, @itemlength) THEN @cluster1 + @cluster2
  487.                                               ELSE @cluster2 + @cluster1
  488.                                           END
  489.                             WHERE ClusterID = @cl1;
  490.                         END -- B
  491.                         ELSE -- D
  492.                         BEGIN
  493.                             SET @i = 1;
  494.                             IF LEN(@cluster1) <= LEN(@cluster2)
  495.                             BEGIN
  496.                                 WHILE @i * @itemlength <= LEN(@cluster1)
  497.                                 BEGIN
  498.                                     UPDATE dbo.Clusters
  499.                                     SET ClusterOnRow = @cl3
  500.                                     WHERE ClusterID = CAST(SUBSTRING(@cluster1,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  501.                                
  502.                                     SET @i = @i + 1;
  503.                                 END
  504.                                 UPDATE dbo.Clusters
  505.                                 SET Cluster = CASE
  506.                                                   WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster2, @itemlength) THEN @cluster1 + @cluster2
  507.                                                   ELSE @cluster2 + @cluster1
  508.                                               END
  509.                                 WHERE ClusterID = @cl3;
  510.                             END
  511.                             ELSE
  512.                             BEGIN
  513.                                 WHILE @i * @itemlength <= LEN(@cluster2)
  514.                                 BEGIN
  515.                                     UPDATE dbo.Clusters
  516.                                     SET ClusterOnRow = @cl1
  517.                                     WHERE ClusterID = CAST(SUBSTRING(@cluster2,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  518.                                
  519.                                     SET @i = @i + 1;
  520.                                 END
  521.                                 UPDATE dbo.Clusters
  522.                                 SET Cluster = CASE
  523.                                                   WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster2, @itemlength) THEN @cluster1 + @cluster2
  524.                                                   ELSE @cluster2 + @cluster1
  525.                                               END
  526.                                 WHERE ClusterID = @cl1;
  527.                             END
  528.                         END -- D
  529.                     END -- B D
  530.                 END -- A B D
  531.                 ELSE -- C E
  532.                 BEGIN
  533.                     IF LEN(@cluster1) = @itemlength -- C
  534.                     BEGIN
  535.                         UPDATE dbo.Clusters
  536.                         SET ClusterOnRow = @clusterOnRow2
  537.                         WHERE ClusterID = @cl1;
  538.  
  539.                         SELECT @cluster3 = Cluster
  540.                         FROM dbo.Clusters
  541.                         WHERE ClusterID = @clusterOnRow2;
  542.  
  543.                         UPDATE dbo.Clusters
  544.                         SET Cluster = CASE
  545.                                           WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster1 + @cluster3
  546.                                           ELSE @cluster3 + @cluster1
  547.                                       END
  548.                         WHERE ClusterID = @clusterOnRow2;
  549.                     END -- C
  550.                     ELSE -- E
  551.                     BEGIN
  552.                         SET @i = 1;
  553.  
  554.                         SELECT @cluster3 = Cluster
  555.                         FROM dbo.Clusters
  556.                         WHERE ClusterID = @clusterOnRow2;
  557.  
  558.                         IF LEN(@cluster1) <= LEN(@cluster3)
  559.                         BEGIN
  560.                             WHILE @i * @itemlength <= LEN(@cluster1)
  561.                             BEGIN
  562.                                 UPDATE dbo.Clusters
  563.                                 SET ClusterOnRow = @clusterOnRow2
  564.                                 WHERE ClusterID = CAST(SUBSTRING(@cluster1,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  565.  
  566.                                 SET @i = @i + 1;
  567.                             END
  568.  
  569.                             UPDATE dbo.Clusters
  570.                             SET Cluster = CASE
  571.                                               WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster1 + @cluster3
  572.                                               ELSE @cluster3 + @cluster1
  573.                                           END
  574.                             WHERE ClusterID = @clusterOnRow2;
  575.                         END
  576.                         ELSE
  577.                         BEGIN
  578.                             WHILE @i * @itemlength <= LEN(@cluster3)
  579.                             BEGIN
  580.                                 UPDATE dbo.Clusters
  581.                                 SET ClusterOnRow = @cl1
  582.                                 WHERE ClusterID = CAST(SUBSTRING(@cluster3,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  583.  
  584.                                 SET @i = @i + 1;
  585.                             END
  586.  
  587.                             UPDATE dbo.Clusters
  588.                             SET Cluster = CASE
  589.                                               WHEN LEFT(@cluster1, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster1 + @cluster3
  590.                                               ELSE @cluster3 + @cluster1
  591.                                           END
  592.                             WHERE ClusterID = @cl1;
  593.                         END
  594.                     END -- E
  595.                 END -- C E
  596.             END -- A B C D E
  597.             ELSE -- C E F
  598.             BEGIN
  599.                 IF @clusterOnRow2 = @cl3 -- C E
  600.                 BEGIN
  601.                     IF LEN(@cluster2) = @itemlength -- C
  602.                     BEGIN
  603.                         UPDATE dbo.Clusters
  604.                         SET ClusterOnRow = @clusterOnRow1
  605.                         WHERE ClusterID = @cl3;
  606.  
  607.                         SELECT @cluster3 = Cluster
  608.                         FROM dbo.Clusters
  609.                         WHERE ClusterID = @clusterOnRow1;
  610.  
  611.                         UPDATE dbo.Clusters
  612.                         SET Cluster = CASE
  613.                                           WHEN LEFT(@cluster2, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster2 + @cluster3
  614.                                           ELSE @cluster3 + @cluster2
  615.                                       END
  616.                         WHERE ClusterID = @clusterOnRow1;
  617.                     END -- C
  618.                     ELSE -- E
  619.                     BEGIN
  620.                         SET @i = 1;
  621.  
  622.                         SELECT @cluster3 = Cluster
  623.                         FROM dbo.Clusters
  624.                         WHERE ClusterID = @clusterOnRow1;
  625.  
  626.                         IF LEN(@cluster2) <= LEN(@cluster3)
  627.                         BEGIN
  628.                             WHILE @i * @itemlength <= LEN(@cluster2)
  629.                             BEGIN
  630.                                 UPDATE dbo.Clusters
  631.                                 SET ClusterOnRow = @clusterOnRow1
  632.                                 WHERE ClusterID = CAST(SUBSTRING(@cluster2,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  633.  
  634.                                 SET @i = @i + 1;
  635.                             END
  636.  
  637.                             UPDATE dbo.Clusters
  638.                             SET Cluster = CASE
  639.                                               WHEN LEFT(@cluster2, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster2 + @cluster3
  640.                                               ELSE @cluster3 + @cluster2
  641.                                           END
  642.                             WHERE ClusterID = @clusterOnRow1;
  643.                         END
  644.                         ELSE
  645.                         BEGIN
  646.                             WHILE @i * @itemlength <= LEN(@cluster3)
  647.                             BEGIN
  648.                                 UPDATE dbo.Clusters
  649.                                 SET ClusterOnRow = @cl3
  650.                                 WHERE ClusterID = CAST(SUBSTRING(@cluster3,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  651.  
  652.                                 SET @i = @i + 1;
  653.                             END
  654.  
  655.                             UPDATE dbo.Clusters
  656.                             SET Cluster = CASE
  657.                                               WHEN LEFT(@cluster2, @itemlength) < LEFT (@cluster3, @itemlength) THEN @cluster2 + @cluster3
  658.                                               ELSE @cluster3 + @cluster2
  659.                                           END
  660.                             WHERE ClusterID = @cl3;
  661.                         END
  662.                     END -- E
  663.                 END  -- C E
  664.                 ELSE -- F
  665.                 BEGIN
  666.                     SELECT @cluster3 = Cluster
  667.                     FROM dbo.Clusters
  668.                     WHERE ClusterID = @clusterOnRow1;
  669.                    
  670.                     SELECT @cluster4 = Cluster
  671.                     FROM dbo.Clusters
  672.                     WHERE ClusterID = @clusterOnRow2;
  673.  
  674.                     SET @i = 1;
  675.                     IF LEN(@cluster3) <= LEN(@cluster4)
  676.                     BEGIN
  677.                         WHILE @i * @itemlength <= LEN(@cluster3)
  678.                         BEGIN
  679.                             UPDATE dbo.Clusters
  680.                             SET ClusterOnRow = @clusterOnRow2
  681.                             WHERE ClusterID = CAST(SUBSTRING(@cluster3,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  682.  
  683.                             SET @i = @i + 1;
  684.                         END
  685.                         UPDATE dbo.Clusters
  686.                         SET Cluster = CASE
  687.                                           WHEN LEFT(@cluster3, @itemlength) < LEFT (@cluster4, @itemlength) THEN @cluster3 + @cluster4
  688.                                           ELSE @cluster4 + @cluster3
  689.                                       END
  690.                         WHERE ClusterID = @clusterOnRow2;
  691.                     END
  692.                     ELSE
  693.                     BEGIN
  694.                         WHILE @i * @itemlength <= LEN(@cluster4)
  695.                         BEGIN
  696.                             UPDATE dbo.Clusters
  697.                             SET ClusterOnRow = @clusterOnRow1
  698.                             WHERE ClusterID = CAST(SUBSTRING(@cluster4,(@i - 1) * @itemlength + 1,@itemlength) AS int);
  699.  
  700.                             SET @i = @i + 1;
  701.                         END
  702.                         UPDATE dbo.Clusters
  703.                         SET Cluster = CASE
  704.                                           WHEN LEFT(@cluster3, @itemlength) < LEFT (@cluster4, @itemlength) THEN @cluster3 + @cluster4
  705.                                           ELSE @cluster4 + @cluster3
  706.                                       END
  707.                         WHERE ClusterID = @clusterOnRow1;
  708.                     END
  709.                 END -- F
  710.             END -- C E F
  711.         END
  712.     END
  713.  
  714.     FETCH NEXT FROM outer_cursor
  715.     INTO @cl1, @cl2, @cl3;
  716.    
  717. END
  718.  
  719. CLOSE outer_cursor;
  720. DEALLOCATE outer_cursor;
  721.  
  722. INSERT INTO dbo.Customers
  723. WITH (TABLOCK)
  724. SELECT
  725.     PurchaseID = r.PurchaseID
  726.    ,CustomerID = CAST(LEFT(c2.Cluster, @itemlength) AS int)
  727. FROM dbo.Rules AS r
  728. JOIN dbo.Clusters AS c1 ON r.ClusterR1 = c1.ClusterID
  729. JOIN dbo.Clusters AS c2 ON c1.ClusterOnRow = c2.ClusterID
  730.  
  731. SET NOCOUNT OFF;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement