从计数子查询中获取最小值

时间:2017-12-04 17:51:28

标签: mysql phpmyadmin

我在试用数据库库存和销售中处理2个表,我正在尝试查找销售数量最少的库存商品。

sales表包含以下字段:sales_id,transaction_id,stock_id,amount 股票表有:sid,upc,名称,描述,金额,价格 当我运行以下SQL时:

  SELECT st.name,
    COUNT( s.stock_id ) AS num_of_individual_sales
    FROM sales AS s
    JOIN stock as st
    ON st.sid = s.stock_id
    GROUP BY s.stock_id

我明白了:

banana  7
mars bar    4
fiery hot monster munch 2
WWII hand grenade   4
cheese toastie  2
fish paste  3
belly fluff 2
Unicorn tears   2
spag sauce  4
cooking oil 2

所以我尝试将其作为子查询包装起来:

SELECT ans.name, MIN(ans.num_of_individual_sales)
FROM
(

SELECT st.name,
COUNT( s.stock_id ) AS num_of_individual_sales
FROM sales AS s
JOIN stock as st
ON st.sid = s.stock_id
GROUP BY s.stock_id

) AS ans

我得到的结果是

香蕉2

即使我的大脑功能不正常也是错误的,我期待得到所有2个(monstermuch,奶酪吐司等)的记录集

我已经尝试了大量不同的组合,但这似乎给出了最接近的结果而不是我想要的结果......

我哪里错了?

欢呼声

更新 在Bill Karwin发布的同时,我对MIN和MAX命令的理解是不准确的。

我已经理解了使用ORDER BY ASC的想法然后我可以使用PHP在COUNT值改变时切断数据但是我有点做这个作为学习练习所以尽管可能更容易路线我希望通过MIN命令仍然可以做到这一点,我想我需要做一个双子查询但是在某个地方迷路了,这是最新的变种。

SELECT st.name, st.price,
s.sales_id
From stock AS st
JOIN sales AS s
ON  st.sid = s.stock_id
WHERE COUNT(s.stock_id)=(

SELECT MIN(ans.num_of_individual_sales)
FROM
(

SELECT st.name,
COUNT( s.stock_id ) AS num_of_individual_sales
FROM sales AS s
JOIN stock as st
ON st.sid = s.stock_id
GROUP BY s.stock_id

) AS ans
)GROUP BY s.stock_id

但是我收到了无效的群组功能错误

3 个答案:

答案 0 :(得分:0)

在您的查询中,name的值不一定来自找到MIN(num_of_individual_sales)的同一行。

考虑这个问题:

SELECT ans.name, MIN(ans.num_of_individual_sales),
  MAX(ans.num_of_individual_sales)
FROM
(
  ...    
) AS ans

在此示例中,应输出name?最小销售额或最大销售额的销售额?如果有多个不同的名称与min或max相关联怎么办?

或者这个查询:

SELECT ans.name, AVG(ans.num_of_individual_sales)
FROM
(
  ...    
) AS ans

如果子查询返回的单行没有完全平均销售数,那么应该返回name?或者不止一行是平均值,但名称不同?

所有这些问题的答案是:如果您正在进行聚合查询,非聚合列会返回不明确的结果。使用严格模式时(默认情况下在MySQL 5.7中),此查询将导致错误。

这里有一个不同的解决方案来获取销售的最小值和相应行的名称:

SELECT ans.name, ans.num_of_individual_sales
FROM
(
  ...    
) AS ans
ORDER BY ans.num_of_individual_sales ASC
LIMIT 1;

答案 1 :(得分:0)

在我看来,您不需要子查询,只需要添加ORDER BY num_of_individual_sales,如果您只想要销售数量最少的3项,则可能需要限制。< / p>

但是您的查询不会包含没有销售的商品;这就是你想要的吗?

也就是说,您只收到一个答案,因为外部查询中没有GROUP BY,因此MIN()从所有结果中找到最小值(但名称是任意一个名称)。只需添加GROUP BY ans.name即可解决问题,但正如我所说,子查询实际上并不需要。

更新(更新问题):

你仍然有一个不必要的子查询级别,你可以避免使用order by和limit,你可以在HAVING中使用分组函数,例如COUNT()而不是WHERE(HADING在分组之后应用,而不是在WHERE之前)虽然你仍然需要告诉外部查询要分组的内容,以避免它将所有行分组:

SELECT st.name, st.price, s.sales_id
FROM stock AS st
JOIN sales AS s
ON st.sid = s.stock_id
GROUP BY st.sid
HAVING COUNT(s.stock_id)=(
    SELECT COUNT(s.stock_id) AS num_of_individual_sales
    FROM sales AS s
    JOIN stock as st
    ON st.sid = s.stock_id
    GROUP BY s.stock_id
    ORDER BY 1
    LIMIT 1
)

(未测试的)

答案 2 :(得分:0)

使用子查询:

SELECT temp1.name, temp1.sales

FROM (SELECT st.stock_name as name,
      COUNT( s.sale_stock_id ) AS sales
      FROM test_sales AS s
      JOIN test_stock as st ON st.stock_id = s.sale_stock_id
      GROUP BY s.sale_stock_id) as temp1

LEFT JOIN (SELECT st.stock_name as name,
           COUNT(s.sale_stock_id ) AS sales
           FROM test_sales AS s
           JOIN test_stock as st ON st.stock_id = s.sale_stock_id
           GROUP BY s.sale_stock_id) as temp2

ON temp1.sales > temp2.sales

WHERE temp2.sales is null