【问题标题】:sql query to divide a value over different recordssql查询将一个值划分为不同的记录
【发布时间】:2014-02-26 01:18:21
【问题描述】:

考虑以下记录集:

1 1000  -1
2 500   2
3 1000 -1
4 500   3
5 500   2
6 1000 -1
7 500   1

所以 3x 一个数字 1000 加上 -1,总计 -3。

4x 一个具有不同值的数字 500

现在我需要一个查询,它将代码 1000 的总和除以 4 个数字 500 并删除代码 1000。 所以最终的结果是这样的:

1 500   1.25
2 500   2.25
3 500   1.25
4 500   0.25

代码总和1000 = -3 表中有 4 次代码 500,必须除以 -3。 -3/4 = -0.75

所以记录“2 500 2”变为“2 500 (2+ -0.75)” = 1.25

作为一个 SQL 新手,我不知道如何完成这项工作,有人可以帮忙吗?

【问题讨论】:

  • 您能解释一下您是如何得到最终结果的吗?您究竟需要哪些数学运算?
  • 那么 1000 和 500 是需要此操作的数字的键吗?还是因为1000个是负数,500个是正数?

标签: sql sql-server tsql


【解决方案1】:

您可以使用 CTE 来“逐步”完成并构建您的解决方案。像这样:

with sumup as
(
  select sum(colb) as s
  from table
  where cola = 1000
), countup as
(
  select count(*) as c
  from table
  where cola = 500
), change as
(
  select s / c as v 
  from sumup, countup
)
select cola, colb - v
from table, change
where cola = 500

需要注意的两点:

这可能不是最快的解决方案,但通常很接近。

您可以轻松测试此代码,只需更改最终选择语句以选择 CTE 的名称并查看它是什么。例如,如果你得到一个不好的结果,这将是一个很好的测试:

with sumup as
(
  select sum(colb) as s
  from table
  where cola = 1000
), countup as
(
  select count(*) as c
  from table
  where cola = 500
), change as
(
  select s / c as v 
  from sumup, countup
)
select * form change

【讨论】:

    【解决方案2】:
     Select col1,( 
    (Select sum(col2 )
       from tab
      where col1 =1000)
      /
      (Select count(*) 
       from tab
       where col1 =500))+Col2 as new_value 
     From tab
     Where col1=500
    

    这里的tab,col1,col2是表名,列有(1000,500)值,列有(1,2,3值)

    【讨论】:

    • 这么多错误。您需要 sum(col3) 并为第二个子查询计数。
    • 我会选择这个看起来最简单的,谢谢
    • 至少霍根应该得到更多的分数。如果没有他的帮助,这将是远远不正确的。
    • @wumpz 我的回答实际上更具可读性。生活就是这么不公平! :-)
    • @hogan ;) 我认为不是,但这里不再计算在内。
    【解决方案3】:

    这将给出你想要的结果:

    DECLARE @T TABLE (ID INT, Number INT, Value INT)
    INSERT @T (ID, Number, Value)
    VALUES
        (1, 1000, -1),
        (2, 500, 2),
        (3, 1000, -1),
        (4, 500, 3),
        (5, 500, 2),
        (6, 1000,-1),
        (7, 500, 1);
    
    
    SELECT  Number, Value, NewValue = Value + (x.Total / COUNT(*) OVER())
    FROM    @T T
            CROSS JOIN 
            (   SELECT  Total = CAST(SUM(Value) AS FLOAT)
                FROM    @T
                WHERE   Number = 1000
            ) x
    WHERE   T.Number = 500;
    

    在交叉连接中,我们只需得到数字为 1000 的总和,这可以像子选择一样简单地完成:

    SELECT  Number, Value, NewValue = Value + ((SELECT CAST(SUM(Value) AS FLOAT) FROM @T WHERE Number = 1000) / COUNT(*) OVER())
    FROM    @T T
    WHERE   T.Number = 500;
    

    或者使用变量:

    DECLARE @Total FLOAT = (SELECT SUM(Value) FROM @T WHERE Number = 1000);
    
    SELECT  Number, Value, NewValue = Value + (@Total / COUNT(*) OVER())
    FROM    @T T
    WHERE   T.Number = 500;
    

    然后使用解析函数COUNT(*) OVER()可以统计结果总数为500。

    【讨论】:

      【解决方案4】:

      这是另一个解决方案:

      select number1, value1, 
      value1 
      + (select sum(value1) from table1 where number1=1000)/
        (select count(*) from table1 where number1=500) calc_value
      from table1 where number1=500
      

      http://sqlfiddle.com/#!6/c68a0/1

      我希望你的问题是正确的。那么这是最好的阅读。

      【讨论】:

        猜你喜欢
        • 2015-11-20
        • 2012-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多