Recent PostsRecent Posts Popular TopicsPopular Topics
 Home Search Members Calendar Who's On

 Addition Of Digits Rate Topic Display Mode Topic Options
Author
 Message
 Posted Sunday, August 5, 2012 8:33 AM
 SSC Journeyman Group: General Forum Members Last Login: Tuesday, May 12, 2015 1:42 AM Points: 78, Visits: 457
 Cool!!! 4 ways to solve the problem! Definitly all go to my KB.CELKO's - is the fastest or isn't it? Who will make a proof test?psCELKO,Are you a Joe Celko, the one, who was the author of marvellous chapter in Itzik Ben Gan book? (Sorry for tactless question). I am really sorry for my poor gramma. And I hope that value of my answers will outweigh the harm for your eyes.Blog: http://somewheresomehow.ruTwitter: @SomewereSomehow
Post #1340276
 Posted Sunday, August 5, 2012 9:04 AM
 SSCrazy Group: General Forum Members Last Login: Today @ 12:12 PM Points: 2,025, Visits: 21,334
 SomewhereSomehow (8/5/2012)...Who will make a proof test?go on...give it a crack ______________________________________________________________you can lead a user to data....but you cannot make them think and remember....every day is a school day
Post #1340278
 Posted Sunday, August 5, 2012 1:36 PM
 SSC Rookie Group: General Forum Members Last Login: 2 days ago @ 9:50 AM Points: 44, Visits: 1,101
 I could be wrong but Celko's method is the fastest. One thing to keep in mind is the LEN function's limit is 8000 characters or in other words the sum of all digits can not exceed 8000...
Post #1340289
 Posted Monday, August 6, 2012 3:10 AM
 SSCommitted Group: General Forum Members Last Login: Today @ 8:44 AM Points: 1,812, Visits: 21,229
 Million row test for three of the solutions. Results are interesting/surpising. Perhaps some of you folks could check this and run it.`--===== Conditionally drop the test table to make reruns in SSMS easier. -- This is NOT a part of the solution. IF OBJECT_ID('tempdb..#Test','U') IS NOT NULL DROP TABLE #Test;--===== Create and populate the test table. -- This is NOT a part of the solution. SELECT TOP (1000000) TestID = IDENTITY(INT,1,1), TestNumber = ABS(CHECKSUM(NEWID())) INTO #Test FROM sys.all_columns ac1 CROSS JOIN sys.all_columns ac2;--===== Add the expected PK ALTER TABLE #Test ADD PRIMARY KEY CLUSTERED (TestID);-----------------------------------------------------------------------------PRINT '========== SomewhereSomehow ==========================================='SET STATISTICS TIME ON;DECLARE @T INT;with nums(n) as(select n from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10))nums(n))select @T = sum(convert(int,substring(convert(varchar(10),TestNumber),n,1)))from numsCROSS JOIN #Testwhere n <= len(convert(varchar(10),TestNumber))GROUP BY TestNumber;SET STATISTICS TIME OFF;GOPRINT '========== CELKO ==========================================='SET STATISTICS TIME ON;DECLARE @T INTSELECT @T = LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (TestNumber AS VARCHAR(150)) ,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'))FROM #Test;SET STATISTICS TIME OFF;GOPRINT '========== Mark ====================================================='SET STATISTICS TIME ON;DECLARE @T INT;WITH Tens(Pos,Val) AS (SELECT 1, 1 UNION ALLSELECT 2, 10 UNION ALLSELECT 3, 100 UNION ALLSELECT 4, 1000 UNION ALLSELECT 5, 10000 UNION ALLSELECT 6, 100000 UNION ALLSELECT 7, 1000000 UNION ALLSELECT 8, 10000000 UNION ALLSELECT 9, 100000000 UNION ALLSELECT 10,1000000000)SELECT @T = SUM((TestNumber / Val) % 10)FROM TensCROSS JOIN #TestWHERE Val<=TestNumberGROUP BY TestNumber;SET STATISTICS TIME OFF;` ____________________________________________________Deja View - The strange feeling that somewhere, sometime you've optimised this query beforeHow to get the best help on a forumhttp://www.sqlservercentral.com/articles/Best+Practices/61537
Post #1340439
 Posted Monday, August 6, 2012 3:41 AM
 SSCrazy Group: General Forum Members Last Login: 2 days ago @ 2:57 AM Points: 2,453, Visits: 7,859
 Mark-101232 (8/6/2012)Million row test for three of the solutions. Results are interesting/surpising. Perhaps some of you folks could check this and run it.Celko forgot to account for the REPLACE "bug".Change his code to this: -`DECLARE @T INT = 985;SELECT LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (@T AS VARCHAR(150)) COLLATE Latin1_General_BIN2,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'));`Then take another look at your test results: -`--===== Conditionally drop the test table to make reruns in SSMS easier. -- This is NOT a part of the solution. IF OBJECT_ID('tempdb..#Test','U') IS NOT NULL DROP TABLE #Test;--===== Create and populate the test table. -- This is NOT a part of the solution. SELECT TOP (1000000) TestID = IDENTITY(INT,1,1), TestNumber = ABS(CHECKSUM(NEWID())) INTO #Test FROM sys.all_columns ac1 CROSS JOIN sys.all_columns ac2;--===== Add the expected PK ALTER TABLE #Test ADD PRIMARY KEY CLUSTERED (TestID);-----------------------------------------------------------------------------PRINT '========== SomewhereSomehow ==========================================='SET STATISTICS TIME ON;DECLARE @T INT;with nums(n) as(select n from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10))nums(n))select @T = sum(convert(int,substring(convert(varchar(10),TestNumber),n,1)))from numsCROSS JOIN #Testwhere n <= len(convert(varchar(10),TestNumber))GROUP BY TestNumber;SET STATISTICS TIME OFF;GOPRINT '========== CELKO ==========================================='SET STATISTICS TIME ON;DECLARE @T INTSELECT @T = LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (TestNumber AS VARCHAR(150)) ,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'))FROM #Test;SET STATISTICS TIME OFF;GOPRINT '========== Mark ====================================================='SET STATISTICS TIME ON;DECLARE @T INT;WITH Tens(Pos,Val) AS (SELECT 1, 1 UNION ALLSELECT 2, 10 UNION ALLSELECT 3, 100 UNION ALLSELECT 4, 1000 UNION ALLSELECT 5, 10000 UNION ALLSELECT 6, 100000 UNION ALLSELECT 7, 1000000 UNION ALLSELECT 8, 10000000 UNION ALLSELECT 9, 100000000 UNION ALLSELECT 10,1000000000)SELECT @T = SUM((TestNumber / Val) % 10)FROM TensCROSS JOIN #TestWHERE Val<=TestNumberGROUP BY TestNumber;SET STATISTICS TIME OFF;GOPRINT '========== IMPROVED CELKO ==========================================='SET STATISTICS TIME ON;DECLARE @T INT;SELECT @T = LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (TestNumber AS VARCHAR(150)) COLLATE Latin1_General_BIN2,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'))FROM #Test;SET STATISTICS TIME OFF;GO``========== SomewhereSomehow =========================================== SQL Server Execution Times: CPU time = 28155 ms, elapsed time = 8756 ms.========== CELKO =========================================== SQL Server Execution Times: CPU time = 24343 ms, elapsed time = 24385 ms.========== Mark ===================================================== SQL Server Execution Times: CPU time = 19921 ms, elapsed time = 6877 ms.========== IMPROVED CELKO =========================================== SQL Server Execution Times: CPU time = 3594 ms, elapsed time = 3619 ms.`--edit--Found the link to the replace "bug" Not a DBA, just trying to learnFor better, quicker answers on T-SQL questions, click on the following...http://www.sqlservercentral.com/articles/Best+Practices/61537/For better, quicker answers on SQL Server performance related questions, click on the following...http://www.sqlservercentral.com/articles/SQLServerCentral/66909/If you litter your database queries with nolock query hints, are you aware of the side effects?Try reading a few of these links...(*) Missing rows with nolock(*) Allocation order scans with nolock(*) Consistency issues with nolock(*) Transient Corruption Errors in SQL Server error log caused by nolock(*) Dirty reads, read errors, reading rows twice and missing rows with nolockLinkedIn
Post #1340465
 Posted Monday, August 6, 2012 3:50 AM
 SSCommitted Group: General Forum Members Last Login: Today @ 8:44 AM Points: 1,812, Visits: 21,229
 Cadavre (8/6/2012)Mark-101232 (8/6/2012)Million row test for three of the solutions. Results are interesting/surpising. Perhaps some of you folks could check this and run it.Celko forgot to account for the REPLACE "bug".Change his code to this: -`DECLARE @T INT = 985;SELECT LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (@T AS VARCHAR(150)) COLLATE Latin1_General_BIN2,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'));`Then take another look at your test results: -`--===== Conditionally drop the test table to make reruns in SSMS easier. -- This is NOT a part of the solution. IF OBJECT_ID('tempdb..#Test','U') IS NOT NULL DROP TABLE #Test;--===== Create and populate the test table. -- This is NOT a part of the solution. SELECT TOP (1000000) TestID = IDENTITY(INT,1,1), TestNumber = ABS(CHECKSUM(NEWID())) INTO #Test FROM sys.all_columns ac1 CROSS JOIN sys.all_columns ac2;--===== Add the expected PK ALTER TABLE #Test ADD PRIMARY KEY CLUSTERED (TestID);-----------------------------------------------------------------------------PRINT '========== SomewhereSomehow ==========================================='SET STATISTICS TIME ON;DECLARE @T INT;with nums(n) as(select n from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10))nums(n))select @T = sum(convert(int,substring(convert(varchar(10),TestNumber),n,1)))from numsCROSS JOIN #Testwhere n <= len(convert(varchar(10),TestNumber))GROUP BY TestNumber;SET STATISTICS TIME OFF;GOPRINT '========== CELKO ==========================================='SET STATISTICS TIME ON;DECLARE @T INTSELECT @T = LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (TestNumber AS VARCHAR(150)) ,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'))FROM #Test;SET STATISTICS TIME OFF;GOPRINT '========== Mark ====================================================='SET STATISTICS TIME ON;DECLARE @T INT;WITH Tens(Pos,Val) AS (SELECT 1, 1 UNION ALLSELECT 2, 10 UNION ALLSELECT 3, 100 UNION ALLSELECT 4, 1000 UNION ALLSELECT 5, 10000 UNION ALLSELECT 6, 100000 UNION ALLSELECT 7, 1000000 UNION ALLSELECT 8, 10000000 UNION ALLSELECT 9, 100000000 UNION ALLSELECT 10,1000000000)SELECT @T = SUM((TestNumber / Val) % 10)FROM TensCROSS JOIN #TestWHERE Val<=TestNumberGROUP BY TestNumber;SET STATISTICS TIME OFF;GOPRINT '========== IMPROVED CELKO ==========================================='SET STATISTICS TIME ON;DECLARE @T INT;SELECT @T = LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (TestNumber AS VARCHAR(150)) COLLATE Latin1_General_BIN2,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'))FROM #Test;SET STATISTICS TIME OFF;GO``========== SomewhereSomehow =========================================== SQL Server Execution Times: CPU time = 28155 ms, elapsed time = 8756 ms.========== CELKO =========================================== SQL Server Execution Times: CPU time = 24343 ms, elapsed time = 24385 ms.========== Mark ===================================================== SQL Server Execution Times: CPU time = 19921 ms, elapsed time = 6877 ms.========== IMPROVED CELKO =========================================== SQL Server Execution Times: CPU time = 3594 ms, elapsed time = 3619 ms.`--edit--Found the link to the replace "bug"That explains a lot, thanks!Also the CELKO solution can be improved a bit by removing the REPLACE(...,'1', '#') - the code is simply counting characters so there's no point changing 1's to #'s. ____________________________________________________Deja View - The strange feeling that somewhere, sometime you've optimised this query beforeHow to get the best help on a forumhttp://www.sqlservercentral.com/articles/Best+Practices/61537
Post #1340471
 Posted Monday, August 6, 2012 3:51 AM
 SSC Rookie Group: General Forum Members Last Login: Tuesday, April 7, 2015 9:11 AM Points: 25, Visits: 125
 declare @string varchar(max) = '25475675675675675675675675675587876865674553334645647656786867879789780890890789676565674545634343453445675756756786867897978978078997896785657454563445345234534645675678768997807867567456342323167567567567567567567567567567567567567567567665756756756756756756756756756756756756756767876879789797287686782567345345289789797278978978978979245645622222245645622222222435645645645646364564564564564564564564564564564564564564564564562'declare @s varchar(1)declare @totalcount int = 0declare @count intset @count = LEN(@string)while (@count != 0)begin set @count = @count - 1 set @s=convert(int,left(@string, 1)) set @string = RIGHT(@string, len(@string)-1) set @totalcount = @totalcount + @send print convert(varchar,@totalcount)Thanks,Sumit Rastogi
Post #1340472
 Posted Monday, August 6, 2012 4:18 AM
 SSC Journeyman Group: General Forum Members Last Login: Tuesday, May 12, 2015 1:42 AM Points: 78, Visits: 457
 Cadavre,Thx for the testing scripts! Especially pointing a bug with replace function (closed as by design).I have quite similar results`========== SomewhereSomehow =========================================== SQL Server Execution Times: CPU time = 19813 ms, elapsed time = 5501 ms. ========== CELKO =========================================== SQL Server Execution Times: CPU time = 20437 ms, elapsed time = 20529 ms. ========== Mark ===================================================== SQL Server Execution Times: CPU time = 12891 ms, elapsed time = 3846 ms. ========== IMPROVED CELKO =========================================== SQL Server Execution Times: CPU time = 2859 ms, elapsed time = 2853 ms.` I am really sorry for my poor gramma. And I hope that value of my answers will outweigh the harm for your eyes.Blog: http://somewheresomehow.ruTwitter: @SomewereSomehow
Post #1340496
 Posted Monday, August 6, 2012 4:53 AM
 SSCrazy Group: General Forum Members Last Login: 2 days ago @ 2:57 AM Points: 2,453, Visits: 7,859
 SomewhereSomehow (8/6/2012)Cadavre,Thx for the testing scripts! Especially pointing a bug with replace function (closed as by design).I have quite similar results`========== SomewhereSomehow =========================================== SQL Server Execution Times: CPU time = 19813 ms, elapsed time = 5501 ms. ========== CELKO =========================================== SQL Server Execution Times: CPU time = 20437 ms, elapsed time = 20529 ms. ========== Mark ===================================================== SQL Server Execution Times: CPU time = 12891 ms, elapsed time = 3846 ms. ========== IMPROVED CELKO =========================================== SQL Server Execution Times: CPU time = 2859 ms, elapsed time = 2853 ms.`Mark's testing scripts, I just improved Celko's solution by taking into account the replace "bug" Not a DBA, just trying to learnFor better, quicker answers on T-SQL questions, click on the following...http://www.sqlservercentral.com/articles/Best+Practices/61537/For better, quicker answers on SQL Server performance related questions, click on the following...http://www.sqlservercentral.com/articles/SQLServerCentral/66909/If you litter your database queries with nolock query hints, are you aware of the side effects?Try reading a few of these links...(*) Missing rows with nolock(*) Allocation order scans with nolock(*) Consistency issues with nolock(*) Transient Corruption Errors in SQL Server error log caused by nolock(*) Dirty reads, read errors, reading rows twice and missing rows with nolockLinkedIn
Post #1340512
 Posted Monday, August 6, 2012 3:47 PM
 SSCommitted Group: General Forum Members Last Login: Today @ 8:44 AM Points: 1,812, Visits: 21,229
 Yet another version and result run on really slow laptop`--===== Conditionally drop the test table to make reruns in SSMS easier. -- This is NOT a part of the solution. IF OBJECT_ID('tempdb..#Test','U') IS NOT NULL DROP TABLE #Test;--===== Create and populate the test table. -- This is NOT a part of the solution. SELECT TOP (1000000) TestID = IDENTITY(INT,1,1), TestNumber = ABS(CHECKSUM(NEWID())) INTO #Test FROM sys.all_columns ac1 CROSS JOIN sys.all_columns ac2;--===== Add the expected PK ALTER TABLE #Test ADD PRIMARY KEY CLUSTERED (TestID);-----------------------------------------------------------------------------PRINT '========== SomewhereSomehow ==========================================='SET STATISTICS TIME ON;DECLARE @T INT;with nums(n) as(select n from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10))nums(n))select @T = sum(convert(int,substring(convert(varchar(10),TestNumber),n,1)))from numsCROSS JOIN #Testwhere n <= len(convert(varchar(10),TestNumber))GROUP BY TestNumber;SET STATISTICS TIME OFF;GOPRINT '========== CELKO ==========================================='SET STATISTICS TIME ON;DECLARE @T INTSELECT @T = LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (TestNumber AS VARCHAR(150)) ,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'))FROM #Test;SET STATISTICS TIME OFF;GOPRINT '========== Mark ====================================================='SET STATISTICS TIME ON;DECLARE @T INT;WITH Tens(Pos,Val) AS (SELECT 1, 1 UNION ALLSELECT 2, 10 UNION ALLSELECT 3, 100 UNION ALLSELECT 4, 1000 UNION ALLSELECT 5, 10000 UNION ALLSELECT 6, 100000 UNION ALLSELECT 7, 1000000 UNION ALLSELECT 8, 10000000 UNION ALLSELECT 9, 100000000 UNION ALLSELECT 10,1000000000)SELECT @T = SUM((TestNumber / Val) % 10)FROM TensCROSS JOIN #TestWHERE Val<=TestNumberGROUP BY TestNumber;SET STATISTICS TIME OFF;GOPRINT '========== IMPROVED CELKO ==========================================='SET STATISTICS TIME ON;DECLARE @T INT;SELECT @T = LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE (CAST (TestNumber AS VARCHAR(150)) COLLATE Latin1_General_BIN2,'0', '') ,'1', '#') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'))FROM #Test;SET STATISTICS TIME OFF;GOPRINT '========== IMPROVED CELKO 2==========================================='SET STATISTICS TIME ON;DECLARE @T INT;SELECT @T = LEN ( REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( REPLACE(REPLACE(REPLACE(REPLACE (CAST (TestNumber AS VARCHAR(150)) COLLATE Latin1_General_BIN2,'0', '') ,'2', '##') ,'3', '###') ,'4', '####') ,'5', '#####') ,'6', '######') ,'7', '#######') ,'8', '########') ,'9', '#########'))FROM #Test;SET STATISTICS TIME OFF;GOPRINT '========== Mark REWRITE====================================================='SET STATISTICS TIME ON;DECLARE @T INT;SELECT @T = (TestNumber % 10) + ((TestNumber/10) % 10) + ((TestNumber/100) % 10) + ((TestNumber/1000) % 10) + ((TestNumber/10000) % 10) + ((TestNumber/100000) % 10) + ((TestNumber/1000000) % 10) + ((TestNumber/10000000) % 10) + ((TestNumber/100000000) % 10) + ((TestNumber/1000000000) % 10)FROM #Test;SET STATISTICS TIME OFF;GO``========== SomewhereSomehow =========================================== SQL Server Execution Times: CPU time = 62000 ms, elapsed time = 58485 ms.========== CELKO =========================================== SQL Server Execution Times: CPU time = 22219 ms, elapsed time = 19565 ms.========== Mark ===================================================== SQL Server Execution Times: CPU time = 36063 ms, elapsed time = 32138 ms.========== IMPROVED CELKO =========================================== SQL Server Execution Times: CPU time = 15000 ms, elapsed time = 13883 ms.========== IMPROVED CELKO 2=========================================== SQL Server Execution Times: CPU time = 14703 ms, elapsed time = 12285 ms.========== Mark REWRITE===================================================== SQL Server Execution Times: CPU time = 2969 ms, elapsed time = 2372 ms.` ____________________________________________________Deja View - The strange feeling that somewhere, sometime you've optimised this query beforeHow to get the best help on a forumhttp://www.sqlservercentral.com/articles/Best+Practices/61537
Post #1340924

 Permissions