【问题标题】:sum of digits in sqlsql中的数字总和
【发布时间】:2016-07-29 18:36:25
【问题描述】:

数据库方案由四个表组成:

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)
  • 产品表包含有关制造商、型号和产品类型(“PC”、“笔记本电脑”或“打印机”)的数据。假定产品表中的型号对于所有制造商和产品类型都是唯一的。

  • PC 表中的每台个人计算机均由唯一代码明确标识,并通过其型号(外键指产品表)、处理器速度(以 MHz 为单位)- 速度字段、RAM 容量进行额外的表征(以 Mb 为单位)- ram、硬盘驱动器容量(以 Gb 为单位)- hd、CD-ROM 速度(例如,“4x”)- cd 及其价格。

  • Laptop 表与 PC 表类似,不同之处在于它包含屏幕尺寸(以英寸为单位)——屏幕而不是 CD-ROM 速度。
  • 对于打印机表中的每个打印机型号,其输出类型('y' 表示彩色,'n' 表示单色)- 颜色字段、打印技术('Laser'、'Jet' 或 'Matrix')- 类型,并指定价格。

计算 Product 表中每个模型的 ID(模型列)中的数字总和。 结果集:模型、数字总和

请告诉我如何解决它。我是中级 sql 技能,无法解决这个问题。

【问题讨论】:

  • 我们修复了您编写的代码。我们不是来为你写的。
  • n % 10 + n / 10 % 10 + n / 100 % 10 ... % 是模数/余数运算,可能是您平台上的mod() 之类的函数。这实际上是一个数学问题,而不是“SQL”问题。如果您的 ID 是字符串,则必须转换为 int。如果它超过 9 个字符,则应使用“bigint”或将其分成几部分。
  • @MarcB SO 所做的远不止“修复您编写的代码”。这不是调试服务。我们通过提供信息和分享知识回答问题一些要求代码的范围狭窄的问题很好。但是,无论您如何描述它,请不要形成我们是来修复其他人代码的观念;这并不比仅仅为人们编写代码更好。
  • 请阅读How-to-Ask 这里是START 了解如何提高问题质量并获得更好答案的好地方。
  • @jpmc26:但我们也有权期望人们先尝试并解决问题。我们也不是代码编写服务。

标签: sql sum


【解决方案1】:

好的,借助两个函数,我们可以将您的型号解析为数字,然后得到数字的总和。

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

好消息是我们可以将它们组合起来,如下图所示

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

返回

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

两个 UDF

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

第二个函数

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

【讨论】:

    【解决方案2】:

    此方案通过检查

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多