【问题标题】:SQL query to divide value across rows that add to total in SQL ServerSQL查询在SQL Server中添加到总计的行之间划分值
【发布时间】:2014-08-31 06:23:12
【问题描述】:

假设我有以下内容

Col1         Col2
1            A      
1            A
1            A
1            B
1            B
1            B
1            B
2            A
2            A
2            B
3            A
3            A
3            A
3            A
3            A
3            A

我需要做的是编写一个查询,确定 Col1 和 Col2 的每个组合的记录数,然后将 1 除以该数字并将该值分配给新列 (Col3),但是我还需要更新记录在某些情况下,因此在对新列求和时,它总是为 Col1 和 Col2 的每个组合加一。

所以,在第一步我会结束

Col1         Col2          NumberofRows
1            A             3
1            B             4
2            A             2
2            B             1
3            A             6

除以 1 的结果

Col1         Col2         Col3
1            A            0.33
1            A            0.33
1            A            0.33
1            B            0.25
1            B            0.25
1            B            0.25
1            B            0.25
2            A            0.5
2            A            0.5
2            B            1
3            A            0.17
3            A            0.17
3            A            0.17
3            A            0.17
3            A            0.17
3            A            0.17

但是,当对 Col1 = 1 和 Col2 = A 的 Col3 求和时,出于显而易见的原因,我们最终得到 0.99 而不是 1。同样,将 Col1=3 和 Col2=A 的 Col3 相加,我们最终得到 1.02。

我该怎么做?

【问题讨论】:

    标签: sql sql-server sum rows divide


    【解决方案1】:

    只有当它们可以表示为整数除以十的倍数时,SQL Server 才能存储精确的数字。由于无法以这种方式表示三分之一,SQL Server 无法在不损失精度的情况下存储三分之一。

    更好的选择是存储行数。行数是整数,SQL Server 可以在不损失精度的情况下存储它们。它们将精确地加起来到总行数。如果显示行,则可以显示1/rc。您显示的内容永远不会加起来,但这是以十进制形式显示数字的限制。

    如果可以将数字显示为分数,您可以:

    select  '1/' + cast(rc as varchar(20))
    

    【讨论】:

      【解决方案2】:

      我尝试使用 CTE。 请在下面查看我的方法:

      ;WITH c1 
      AS
      ( SELECT col1, col2, count(*) as Cnt
        FROM test
        GROUP BY col1, col2
      ),
      c2 
      AS
      ( SELECT t.col1, t.col2, cast(cast(1 as decimal(5, 2))/grpCount.Cnt as decimal(5, 2))
        AS Cnt, 1%grpCount.Cnt AS roundedCount
        FROM test t
        JOIN (SELECT * FROM c1) AS grpCount
       ON grpCount.col1 = t.col1 AND grpCount.col2 = t.col2
      )
      SELECT * FROM c2;
      

      SQL 小提琴:- http://sqlfiddle.com/#!6/fe268/7

      【讨论】:

        【解决方案3】:

        您需要确保 SQL 使用中间值作为浮点数,然后在显示时转换为十进制 2 d.p

        SQL Fiddle

        MS SQL Server 2012 架构设置

        CREATE TABLE tableA
        (
            Col1 int,
            Col2 VARCHAR(1)
        )
        
        INSERT INTO tableA 
        VALUES
            (1,'A'),
            (1,'A'),
            (1,'A'),
            (1,'B'),
            (1,'B'),
            (1,'B'),
            (1,'B'),
            (2,'A'),
            (2,'A'),
            (2,'B'),
            (3,'A'),
            (3,'A'),
            (3,'A'),
            (3,'A'),
            (3,'A'),
            (3,'A')
        

        查询 1

        ;WITH cnt
        AS
        (
            SELECT Col1, Col2, 1.0 / COUNT(*)  cnt
            FROM tableA
            GROUP BY Col1, Col2
        )
        SELECT A.Col1, A.Col2, CAST(SUM(cnt) AS decimal(4,2))
        FROM tableA A
        INNER JOIN cnt
            ON A.Col1 = cnt.Col1 AND A.Col2 = cnt.Col2
        GROUP BY A.Col1, A.Col2
        

        Results

        | COL1 | COL2 | COLUMN_2 |
        |------|------|----------|
        |    1 |    A |        1 |
        |    1 |    B |        1 |
        |    2 |    A |        1 |
        |    2 |    B |        1 |
        |    3 |    A |        1 |
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-30
          • 2020-10-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-13
          • 1970-01-01
          相关资源
          最近更新 更多