2

我有一个问题很容易计算一些简单的平均值。我的桌子:

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 可以为我做点什么。

4

6 回答 6

7
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

于 2012-10-10T21:28:21.293 回答
3

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

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

于 2012-10-10T21:24:00.200 回答
2

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

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

于 2012-10-10T21:22:01.277 回答
2

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

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
于 2012-10-10T21:17:27.877 回答
0

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

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
)
于 2012-10-10T21:16:55.263 回答
0

你的桌子设计看起来不太好。

改为制作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
于 2012-10-10T21:13:16.927 回答