MySQL查询使用多个表中的数据计算最新平均价格 [英] MySQL query to calculate latest average prices using data from multiple tables

查看:150
本文介绍了MySQL查询使用多个表中的数据计算最新平均价格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究基于PHP和MySQL的系统,以组织餐馆的产品和费用.

我将数据整理成四个表.

项目表

id | name
1  | Beer
2  | Vodka

产品表

id | item_id | name
1  |    1    | Budweiser
2  |    1    | Sam Adams
3  |    2    | Smirnoff
4  |    2    | Grey Goose

供应商表

id | name
1  | Supplier 1
2  | Supplier 2

费用表

id | product_id | cost | quantity | supplier | date
1  |     1      | 2.99 |     1    |     1    |  2017-09-05
2  |     1      | 3.00 |     2    |     2    |  2017-09-10
3  |     1      | 2.50 |     1    |     1    |  2017-09-20
4  |     1      | 3.98 |     2    |     1    |  2017-09-22
5  |     1      | 4.00 |     1    |     2    |  2017-09-25
6  |     1      | 8.00 |     2    |     2    |  2017-09-27

我想编写一个MYSQL查询,该查询可以基于费用表(基于日期)中最新的3个整体的平均每件商品的平均成本(成本/数量)来找出特定产品的最便宜供应商./p>

这就是我要计算的:

供应商1个最后3个条目-单位成本:2.99、2.50和1.99.平均值= 2.49

供应商2个最后3个条目-每单位成本:1.50、4.00和4.00.平均值= 3.16

因此,SQL应该返回供应商1"是产品1(百威啤酒)的最便宜选择.

到目前为止,我已经尝试过了,但是我有点迷茫和困惑:

select * from products 
INNER JOIN expenses
ON products.id = expenses.product
AND products.item = '1'
ORDER BY (expenses.cost/expenses.quantity)
LIMIT 3;

此查询的输出与我要弄清楚的是很长的距离:(:

id | item_id |  name   | id | product_id | cost | quantity | supplier | date
1  |    1    |Budweiser| 2  |     1      | 3.00 |    2     |    2     | 2017-09-10
1  |    1    |Budweiser| 4  |     1      | 3.98 |    2     |    1     | 2017-09-22
1  |    1    |Budweiser| 3  |     1      | 2.50 |    1     |    1     | 2017-09-20

基于示例数据,我正在寻找的输出将是:

cheapest_supplier
        1

解决方案

我想编写一个MYSQL查询,该查询可以根据平均每笔费用找出特定产品的最便宜供应商 费用表中的最近的3个全部的项目(成本/数量) (基于日期).

选项将是与用户变量配合使用以基于日期生成排名的查询. 并且仅选择最后三个日期.

查询

SELECT 
 *
FROM (
   SELECT 
   * 
   , CASE 
       WHEN @supplier = supplier
       THEN @rank := @rank + 1 
       ELSE @rank := 1
     END 
      AS rank
   , @supplier := supplier 
   FROM 
     Expenses 
   CROSS JOIN (
    SELECT
       @supplier := NULL
     , @rank := 0
    ) 
    AS
      init_user_params  
   WHERE
      product_id = 1       
   ORDER BY
      supplier ASC 
    , DATE DESC   
)
 AS Expenses_ranked 
WHERE
  Expenses_ranked.rank <= 3

结果

    id  product_id  cost    quantity  supplier  date        @supplier := NULL  @rank := 0    rank  @supplier := supplier  
------  ----------  ------  --------  --------  ----------  -----------------  ----------  ------  -----------------------
     4           1  3.98           2         1  2017-09-22  (NULL)                      0       1                        1
     3           1  2.50           1         1  2017-09-20  (NULL)                      0       2                        1
     1           1  2.99           1         1  2017-09-05  (NULL)                      0       3                        1
     6           1  8.00           2         2  2017-09-27  (NULL)                      0       1                        2
     5           1  4.00           1         2  2017-09-25  (NULL)                      0       2                        2
     2           1  3.00           2         2  2017-09-10  (NULL)                      0       3                        2

使用该结果为每个供应商生成平均清单.

查询

SELECT 
   Expenses_ranked.supplier 
 , AVG(Expenses_ranked.cost / Expenses_ranked.quantity) AS AVG
FROM ( 

  SELECT 
   * 
   , CASE 
       WHEN @supplier = supplier
       THEN @rank := @rank + 1 
       ELSE @rank := 1
     END 
      AS rank
   , @supplier := supplier 
   FROM 
     Expenses 
   CROSS JOIN (
    SELECT
       @supplier := NULL
     , @rank := 0
    ) 
    AS
      init_user_params  
   WHERE
      product_id = 1       
   ORDER BY
      supplier ASC 
    , DATE DESC   
)
 AS Expenses_ranked 
WHERE
  Expenses_ranked.rank <= 3
GROUP BY
  Expenses_ranked.supplier 

结果

supplier  avg           
--------  --------------
       1  2.4933333333  
       2  3.1666666667  

现在我们可以使用简单的ORDER BY [] ASC LIMIT 1来获取最便宜的供应商

查询

SELECT 
 Expenses_ranked_avg.supplier AS cheapest_supplier
FROM ( 

  SELECT 
     Expenses_ranked.supplier 
   , AVG(Expenses_ranked.cost / Expenses_ranked.quantity) AS AVG
  FROM ( 

    SELECT 
     * 
     , CASE 
         WHEN @supplier = supplier
         THEN @rank := @rank + 1 
         ELSE @rank := 1
       END 
      AS rank
   , @supplier := supplier 
   FROM 
     Expenses 
   CROSS JOIN (
    SELECT
       @supplier := NULL
     , @rank := 0
    ) 
    AS
      init_user_params  
   WHERE
      product_id = 1       
   ORDER BY
      supplier ASC 
    , DATE DESC   
    )
      AS
        Expenses_ranked 
    WHERE
      Expenses_ranked.rank <= 3
    GROUP BY
      Expenses_ranked.supplier 
)
  AS Expenses_ranked_avg 
ORDER BY 
 Expenses_ranked_avg.avg ASC
LIMIT 1

结果

cheapest_supplier  
-------------------
                  1

更多最佳查询.

还可以在where语句中声明用户变量. 直接过滤掉排名成为可能.

查询

  SELECT 
   *
  FROM
   Expenses 
  WHERE
   (
     CASE 
       WHEN @supplier = supplier
       THEN @rank := @rank + 1 
       ELSE @rank := 1
     END  
   ) 
 AND
   (@supplier := supplier )
 AND  
   @rank <= 3  
 AND  
   product_id = 1
ORDER BY 
   supplier ASC
 , DATE ASC  

结果

    id  product_id  cost    quantity  supplier  date        
------  ----------  ------  --------  --------  ------------
     1           1  2.99           1         1  2017-09-05  
     3           1  2.50           1         1  2017-09-20  
     4           1  3.98           2         1  2017-09-22  
     2           1  3.00           2         2  2017-09-10  
     5           1  4.00           1         2  2017-09-25  
     6           1  8.00           2         2  2017-09-27 

现在,使用此结果集轻松找到最便宜的供应商.

查询

SELECT 
   Expenses_ranked.supplier AS cheapest_supplier
FROM (  

  SELECT 
   *
  FROM
   Expenses 
  WHERE
   (
     CASE 
       WHEN @supplier = supplier
       THEN @rank := @rank + 1 
       ELSE @rank := 1
     END  
   ) IS NOT NULL 
 AND
   (@supplier := supplier ) IS NOT NULL
 AND  
   @rank <= 3  
 AND  
   product_id = 1
ORDER BY 
   supplier ASC
 , DATE ASC  
)
 AS Expenses_ranked 
GROUP BY
  Expenses_ranked.supplier
ORDER BY 
  AVG(Expenses_ranked.cost / Expenses_ranked.quantity) ASC
LIMIT 1  

结果

cheapest_supplier  
-------------------
                  1

I am working on a PHP and MySQL based system to organise products and expenses for a restaurant.

I have data organised in to four tables.

Items table

id | name
1  | Beer
2  | Vodka

Products table

id | item_id | name
1  |    1    | Budweiser
2  |    1    | Sam Adams
3  |    2    | Smirnoff
4  |    2    | Grey Goose

Supplier table

id | name
1  | Supplier 1
2  | Supplier 2

Expenses table

id | product_id | cost | quantity | supplier | date
1  |     1      | 2.99 |     1    |     1    |  2017-09-05
2  |     1      | 3.00 |     2    |     2    |  2017-09-10
3  |     1      | 2.50 |     1    |     1    |  2017-09-20
4  |     1      | 3.98 |     2    |     1    |  2017-09-22
5  |     1      | 4.00 |     1    |     2    |  2017-09-25
6  |     1      | 8.00 |     2    |     2    |  2017-09-27

I would like to write a MYSQL Query that can figure out the cheapest supplier of a specific product based on the average cost per item (cost/quantity) of the latest 3 entires in the expenses table (based on date).

Here's what I want to compute:

Supplier 1 last 3 entries - costs per unit of: 2.99, 2.50 and 1.99. Average = 2.49

Supplier 2 last 3 entries - costs per unit of: 1.50, 4.00 and 4.00. Average = 3.16

So the SQL should return that Supplier 1 is the cheapest option for Product 1 (Budweiser).

So far I have attempted this, but I am a bit lost and confused:

select * from products 
INNER JOIN expenses
ON products.id = expenses.product
AND products.item = '1'
ORDER BY (expenses.cost/expenses.quantity)
LIMIT 3;

The output of this query is which is a long way from what I'm trying to figure out :(:

id | item_id |  name   | id | product_id | cost | quantity | supplier | date
1  |    1    |Budweiser| 2  |     1      | 3.00 |    2     |    2     | 2017-09-10
1  |    1    |Budweiser| 4  |     1      | 3.98 |    2     |    1     | 2017-09-22
1  |    1    |Budweiser| 3  |     1      | 2.50 |    1     |    1     | 2017-09-20

The output I am looking for based on the sample data would be:

cheapest_supplier
        1

解决方案

I would like to write a MYSQL Query that can figure out the cheapest supplier of a specific product based on the average cost per item (cost/quantity) of the latest 3 entires in the expenses table (based on date).

A option would be a query that works with user variables to generate a ranking based on date. And only select the three last dates.

Query

SELECT 
 *
FROM (
   SELECT 
   * 
   , CASE 
       WHEN @supplier = supplier
       THEN @rank := @rank + 1 
       ELSE @rank := 1
     END 
      AS rank
   , @supplier := supplier 
   FROM 
     Expenses 
   CROSS JOIN (
    SELECT
       @supplier := NULL
     , @rank := 0
    ) 
    AS
      init_user_params  
   WHERE
      product_id = 1       
   ORDER BY
      supplier ASC 
    , DATE DESC   
)
 AS Expenses_ranked 
WHERE
  Expenses_ranked.rank <= 3

Result

    id  product_id  cost    quantity  supplier  date        @supplier := NULL  @rank := 0    rank  @supplier := supplier  
------  ----------  ------  --------  --------  ----------  -----------------  ----------  ------  -----------------------
     4           1  3.98           2         1  2017-09-22  (NULL)                      0       1                        1
     3           1  2.50           1         1  2017-09-20  (NULL)                      0       2                        1
     1           1  2.99           1         1  2017-09-05  (NULL)                      0       3                        1
     6           1  8.00           2         2  2017-09-27  (NULL)                      0       1                        2
     5           1  4.00           1         2  2017-09-25  (NULL)                      0       2                        2
     2           1  3.00           2         2  2017-09-10  (NULL)                      0       3                        2

Using that results to generate a avg list per supplier.

Query

SELECT 
   Expenses_ranked.supplier 
 , AVG(Expenses_ranked.cost / Expenses_ranked.quantity) AS AVG
FROM ( 

  SELECT 
   * 
   , CASE 
       WHEN @supplier = supplier
       THEN @rank := @rank + 1 
       ELSE @rank := 1
     END 
      AS rank
   , @supplier := supplier 
   FROM 
     Expenses 
   CROSS JOIN (
    SELECT
       @supplier := NULL
     , @rank := 0
    ) 
    AS
      init_user_params  
   WHERE
      product_id = 1       
   ORDER BY
      supplier ASC 
    , DATE DESC   
)
 AS Expenses_ranked 
WHERE
  Expenses_ranked.rank <= 3
GROUP BY
  Expenses_ranked.supplier 

Result

supplier  avg           
--------  --------------
       1  2.4933333333  
       2  3.1666666667  

Now we can use a simple ORDER BY [] ASC LIMIT 1 to get the cheapest supplier

Query

SELECT 
 Expenses_ranked_avg.supplier AS cheapest_supplier
FROM ( 

  SELECT 
     Expenses_ranked.supplier 
   , AVG(Expenses_ranked.cost / Expenses_ranked.quantity) AS AVG
  FROM ( 

    SELECT 
     * 
     , CASE 
         WHEN @supplier = supplier
         THEN @rank := @rank + 1 
         ELSE @rank := 1
       END 
      AS rank
   , @supplier := supplier 
   FROM 
     Expenses 
   CROSS JOIN (
    SELECT
       @supplier := NULL
     , @rank := 0
    ) 
    AS
      init_user_params  
   WHERE
      product_id = 1       
   ORDER BY
      supplier ASC 
    , DATE DESC   
    )
      AS
        Expenses_ranked 
    WHERE
      Expenses_ranked.rank <= 3
    GROUP BY
      Expenses_ranked.supplier 
)
  AS Expenses_ranked_avg 
ORDER BY 
 Expenses_ranked_avg.avg ASC
LIMIT 1

Result

cheapest_supplier  
-------------------
                  1

More optimal queries.

What also is possible to declare the user variables within the where statement. Making it directly possible to filter out the ranking.

Query

  SELECT 
   *
  FROM
   Expenses 
  WHERE
   (
     CASE 
       WHEN @supplier = supplier
       THEN @rank := @rank + 1 
       ELSE @rank := 1
     END  
   ) 
 AND
   (@supplier := supplier )
 AND  
   @rank <= 3  
 AND  
   product_id = 1
ORDER BY 
   supplier ASC
 , DATE ASC  

Result

    id  product_id  cost    quantity  supplier  date        
------  ----------  ------  --------  --------  ------------
     1           1  2.99           1         1  2017-09-05  
     3           1  2.50           1         1  2017-09-20  
     4           1  3.98           2         1  2017-09-22  
     2           1  3.00           2         2  2017-09-10  
     5           1  4.00           1         2  2017-09-25  
     6           1  8.00           2         2  2017-09-27 

Now it's easy the use this result set to find the cheapest supplier.

Query

SELECT 
   Expenses_ranked.supplier AS cheapest_supplier
FROM (  

  SELECT 
   *
  FROM
   Expenses 
  WHERE
   (
     CASE 
       WHEN @supplier = supplier
       THEN @rank := @rank + 1 
       ELSE @rank := 1
     END  
   ) IS NOT NULL 
 AND
   (@supplier := supplier ) IS NOT NULL
 AND  
   @rank <= 3  
 AND  
   product_id = 1
ORDER BY 
   supplier ASC
 , DATE ASC  
)
 AS Expenses_ranked 
GROUP BY
  Expenses_ranked.supplier
ORDER BY 
  AVG(Expenses_ranked.cost / Expenses_ranked.quantity) ASC
LIMIT 1  

Result

cheapest_supplier  
-------------------
                  1

这篇关于MySQL查询使用多个表中的数据计算最新平均价格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆