【问题标题】:Get the average with quantity用数量求平均值
【发布时间】:2012-10-10 21:09:01
【问题描述】:

我很难计算一些简单的平均值。我的桌子:

id / user / action     / data
1  / a    / unit_price / 40
2  / a    / quantity   / 1
3  / b    / unit_price / 70
4  / b    / quantity   / 2

Unit_price 是用户的价格,数量是数量。所以我应该得到: (40 + 70 + 70) / 3 = 60

如果我做一个

(AVG(action) WHERE action = unit_price)

我明白了:

(70+40)/2 = 55

如果我做一个

(SUM(action) WHERE action = unit_price) / (SUM(action) WHERE action = quantity)

我明白了:

110 / 3 = 36.6

我发现的最简单的方法是不要放 unit_price 而是放全局价格,然后在 PHP 代码中进行划分以获得 unit_price,但我希望 SQL 可以为我做点什么。

【问题讨论】:

  • 我认为您的任何解决方案都不起作用,但我需要更具体:1/这只是全局请求的一部分,所以我认为我将无法添加更多加入并在 SELECT 2/ 中获取列 unit_price 和单独的列数量不会改变问题 3/ 是的,我不想要特定用户的平均价格,但全局 4/ 正确答案通过数量的乘积和每个用户的单位价格,然后是经典的平均数学
  • Lamak 和 Olivier 的回答似乎完美地回答了您的问题。 (在某些假设下)bluefeet 和 Raphael 也是如此。如果您的查询/要求更复杂,则回答者没有精神力量来猜测它们是什么。
  • 好的,我得到了很好的答案。只需要找出如何将其放入我的大查询中。谢谢大家

标签: sql math sum average


【解决方案1】:
select coalesce(sum(quantity * unit_price) /sum(quantity), 0) from
(select 
   sum(case when action='unit_price' then data else 0 end) as unit_price,
   sum(case when action='quantity' then data else 0 end) as quantity 
 from test
group by user) as a

SqlFiddle

【讨论】:

  • Raphael - SQL Fiddle 快速提示 - 您可以将 OP 的示例数据复制并粘贴到“Text to DDL”工具中,以快速构建查询所需的表和数据。例如,这是您针对我通过这样做构建的架构运行的查询:sqlfiddle.com/#!2/dfd1a/1
  • @JakeFeasel 哦,哦,你拯救了我的一天(这才刚刚开始,这是一个好的开始)。谢谢!
【解决方案2】:

您可以使用类似这样的方法,它基本上将数据转换为更可用的格式,然后获取您需要的值:

select avg(unit_price) AvgUnitPrice, 
  sum(unit_price*quantity)/sum(quantity) AvgPrice
from
(
  select user,
    max(case when action = 'unit_price' then data end) unit_price,
    max(case when action = 'quantity' then data end) quantity
  from table1
  group by user
) x;

见SQL Fiddle With Demo

【讨论】:

    【解决方案3】:

    好的,显然您的表格设计不是最佳的,您应该将unit_price 和quantity 作为单独的列。但是,使用你所拥有的,试试这个:

    SELECT SUM(A.data*B.data)/SUM(B.data) Calculation
    FROM (  SELECT user, data
            FROM YourTable
            WHERE action = 'unit_price') AS A
    INNER JOIN (SELECT user, data
                FROM YourTable
                WHERE action = 'quantity') AS B
    ON A.user = B.user
    

    【讨论】:

    • OPs 问题需要澄清,但似乎他希望结果是(单价之和)/(数量之和),而不是由用户将其归结。
    • @Jim - 我误读了这个问题,尽管我认为操作员想要一些与我发布的内容不同的东西,所以我更新了我的答案以反映这一点。
    • @ypercube - 这是从哪里来的?
    【解决方案4】:

    我会将表连接到自身,以便将两条记录放在一起

    SELECT
        SUM(unit_price * quantity) / SUM(quantity) AS average_unit_price
    FROM
        (SELECT
            U.data AS unit_price, Q.data AS quantity
        FROM
            theTable U
            INNER JOIN theTable Q
                ON U.user = Q.user
        WHERE
            U.action = 'unit_price' AND
            Q.action = 'quantity')
    

    如果每个用户有两个以上的记录,并且这两个记录的 id 是连续的,那么您必须将 WHERE 子句更改为

        WHERE
            U.action = 'unit_price' AND
            Q.action = 'quantity' AND
            U.id + 1 = Q.id 
    

    注意:

    如果你计算AVG(unit_price * quantity),你会得到每个用户的平均总和。

    (1*40 + 2*70) / 2 = 90

    如果你计算SUM(unit_price * quantity) / SUM(quantity),你会得到平均单价。

    (1*40 + 2*70) / 3 = 60

    【讨论】:

    • 但我只有一张桌子。为什么选择 A 和 B?我不明白。 (我在我的问题中添加了一个更具体的评论)
    • A 和 B 是别名(我现在将它们分别更改为 U 的 unit_price 和 Q 的数量)。只有一张桌子(theTable),但我用了两次。一旦我给它命名U 和一次Q。这使我可以将它们视为两个不同的表。从U我只取单价记录,从Q只取数量记录,由用户加入。此查询用作子查询,因此位于括号 () 之间。它被用作具有两列 unit_price 和 quantity 的新表,并用作外部 SELECT 的源表。
    【解决方案5】:

    这样的事情应该可行;语法可能不完美,因为我没有尝试过,但至少你明白了主要思想。

    SELECT sumUnitPrice.sum / sumQuantity.sum
    FROM
    (
      (SELECT SUM(data) as sum
      FROM WhateverTheHellYourTableIsNamed
      WHERE action = 'unit_price') sumUnitPrice
    
      (SELECT SUM(data) as sum
      FROM WhateverTheHellYourTableIsNamed
      WHERE action = 'quantity') sumQuantity
    )
    

    【讨论】:

      【解决方案6】:

      你的桌子设计不好看。

      改为制作 2 个表格:

      ITEM
         ItemId int not null PK, 
         Name varchar(200) not null, 
         UnitPrice decimal (10,2) not null
      
      SALES
         SalesId int not null PK, 
         ItemId int not null FK, 
         Quantity decimal(10,2)
      

      PK - 主键,FK - 外键

      平均:

      select 
        I.Name, avg(I.UnitPrice * S.Quantity) as avgSales
      from 
        Sales S 
        join Items I on I.ItemId = S.ItemId
      group by 
        I.Name
      

      【讨论】:

      • 虽然表结构可能不理想,但有时无法更改架构。考虑到他当前的模式,OP 的要求是完全可能的。
      • 是的,我同意,但我们应该明确表示该解决方案并不“理想”。如果有原因,应该明确说明。
      • 嗯,我知道它看起来像一个简单的订单网站,但事实并非如此,我真的需要在同一张表中获取这两个信息。我应该说的是,我的全局查询比我显示的部分复杂得多......
      • 我在我的问题中添加评论以更具体
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 2022-08-18
      • 2022-01-19
      • 2012-10-30
      • 2017-06-13
      • 1970-01-01
      相关资源
      最近更新 更多