mitzy
mitzy

Reputation: 39

sum of digits in sql

The database scheme consists of four tables:

Product(maker, model, type)    
PC(code, model, speed, ram, hd, cd, price)    
Laptop(code, model, speed, ram, hd, screen, price)    
Printer(code, model, color, type, price)

Calculate the sum of digits in each model's ID (model column) from Product table. Result set: model, sum of digits

Please tell me how to solve it. I am of intermediate sql skill and cant solve this.

Upvotes: 0

Views: 3754

Answers (3)

Nadezhda GR
Nadezhda GR

Reputation: 27

It's quite interesting, that my solution with LEN method hasn't passes the check. The only difference is the method.

According to documentation the main difference between LEN and DATALENGTH is that DATALENGTH counts bytes, LEN counts symbols.

So it looks like that LEN method is better for the task. But stiil we can pass chech only with DATALENGTH .

SELECT 
    model, 
    1 * (len(model) - len(replace(model,'1',''))) +
    2 * (len(model) - len(replace(model,'2',''))) +
    3 * (len(model) - len(replace(model,'3',''))) +
    4 * (len(model) - len(replace(model,'4',''))) +
    5 * (len(model) - len(replace(model,'5',''))) +
    6 * (len(model) - len(replace(model,'6',''))) +
    7 * (len(model) - len(replace(model,'7',''))) +
    8 * (len(model) - len(replace(model,'8',''))) +
    9 * (len(model) - len(replace(model,'9','')))  AS 'sum_fig'
FROM product

Upvotes: -1

Eugeny K
Eugeny K

Reputation: 76

This solution passes the check

SELECT model, 
    1 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '1', ''))) +
    2 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '2', ''))) +
    3 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '3', ''))) +
    4 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '4', ''))) +
    5 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '5', ''))) +
    6 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '6', ''))) +
    7 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '7', ''))) +
    8 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '8', ''))) +
    9 * (DATALENGTH(model) - DATALENGTH(REPLACE(model, '9', ''))) AS 'qty'
FROM product

Upvotes: 1

John Cappelletti
John Cappelletti

Reputation: 81950

OK, with the help of two functions, we can parse your model numbers into digits and then get the sum of digits.

Select [dbo].[udf-Stat-Sum-of-Digits](12345)     -- Returns 15
Select [dbo].[dbo].[udf-Str-Numbers]('AF567-56') -- Returns 56756

The good news is that we can combine these as illustrated below

Declare @Table table (model varchar(50))
Insert into @Table values
('AF567-56'),
('25-a-467'),
('11156 25')

Select Model
      ,Digits = [dbo].[udf-Str-Numbers](Model)
      ,SumOfDigits = [dbo].[udf-Stat-Sum-of-Digits]([dbo].[udf-Str-Numbers](Model))
 From  @Table

Returns

Model       Digits  SumOfDigits
AF567-56    56756   29
25-a-467    25467   24
11156 25    1115625 21

The two UDFs

CREATE Function [dbo].[udf-Stat-Sum-of-Digits](@Val int)
Returns Int
As
Begin

Declare @RetVal as int

;with i AS (
    Select @Val / 10 n, @Val % 10 d
    Union ALL
    Select n / 10, n % 10
    From i
    Where n > 0
)
Select @RetVal = SUM(d) FROM i;

Return @RetVal

END

The second Function

CREATE FUNCTION [dbo].[udf-Str-Numbers](@String varchar(250))
Returns Varchar(250)
As
Begin
    Declare @RetVal varchar(250) = @String
    ;with cteChar as (Select Cnt=1,Str=Char(1) Union All Select Cnt=B.Cnt+1,Str=Char(B.Cnt+1) From cteChar as B Where B.Cnt <= 255)
    Select @RetVal = Replace(@RetVal,Str,'') From cteChar where str not like '[0-9]' Option (maxrecursion 256)
    Return case when IsNull(@RetVal,'')='' then @String else @RetVal end
END

Upvotes: 2

Related Questions