【问题标题】:multiply rows in t-sql在 t-sql 中乘以行
【发布时间】:2014-12-24 23:00:38
【问题描述】:

我有下表

 ID     Number    
----------------     
   1       41.5
   2       42.5
   3       43.5
   2       44.5   
   2       45.5
   1       46.5
   1       47.5

我需要编写一个查询,该查询将返回不同的 ID 和相应的 Number 列值相乘。对于给定的表结果应该是这样的

ID       Result 
-----------------
  1         41.5 * 46.5 * 47.5
  2         42.5 * 44.5 * 45.5
  3         etc...

(不使用游标)

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql


    【解决方案1】:
    SELECT Id, EXP(SUM(LOG(Number))) as Result
    FROM Scores 
    GROUP BY id
    

    这适用于正数,也可以乘负数,您可以使用ABS() 函数来使用绝对(正)值,但最终结果将是正数而不是负数:

    SELECT Id, EXP(SUM(LOG(ABS(Number)))) as Result
    FROM Scores 
    GROUP BY id
    

    编辑:添加测试脚本

    DECLARE @data TABLE(id int, number float)
    
    INSERT INTO @data VALUES
    (1, 2.2),
    (1, 10),
    (2, -5.5),
    (2, 10)
    
    SELECT Id, EXP(SUM(LOG(ABS(Number)))) as Result 
    FROM @data GROUP BY id 
    

    输出:

    1   22
    2   55
    

    【讨论】:

    • 我也看到了,但我有点怀疑在应该是简单的算术中涉及像 EXPLOG 这样的复杂计算。也不适用于负数,但这里的第一条评论有一个解决方法:sqlblogcasts.com/blogs/madhivanan/archive/2007/11/13/…
    • EXP 不是聚合函数
    • @mellamokb : 比较执行计划会很有趣
    • @Nario : 我已经添加了测试脚本,所以你可以试试看 EXP 是否适用于 GROUP BY
    • @Nario EXP 不是聚合函数,但在这里它在 sum 之后调用。所以最后它只在每行一个数字上运行,而且它工作得很好。一种思考方式是 Sum 在将聚合列传递给 Exp 之前对其进行包装。
    【解决方案2】:
    select id, power(sum(log10(num)),10) group by id
    

    【讨论】:

      【解决方案3】:

      这是行连接的一个细微变化,Jeff Moden 在 SQL Server Central 上有一篇很棒的文章,标题为 Performance Tuning: Concatenation Functions and Some Tuning Myths


      编辑:@mellamokb 它类似于串联,但需要一些修改。一个示例脚本是

      create table testMult (id int, num int)
      
      GO
      
      insert into testMult values (1, 2)
      insert into testMult values (1, 3)
      insert into testMult values (1, 4)
      insert into testMult values (2, 2)
      
      GO
      
      create function dbo.fnMult (@someId int)
      returns int as 
      begin
          declare @return int
          set @return = 1
      
          select @return = @return * num
          from testMult
          where id = @someId
      
          return @return
      end
      
      GO
      
      select * 
      from testMult
      
      select t1.id,
          dbo.fnMult(t1.id) 
      from testMult t1
      group by t1.id
      

      这只是 Jeff Moden 在他的文章中提供的脚本的一个非常小的变化。

      【讨论】:

      • 你误读了他的问题,就像我第一次做的一样 :) 这是乘法,而不是串联。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 2014-05-29
      • 2013-01-18
      • 2016-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多