Sql 按从分组中排除列

Sql 按从分组中排除列,sql,group-by,min,Sql,Group By,Min,我有一张表,Supplies,列出了不同供应商的产品价格: | ID | Item | Price | Supplier | ID是主键(只是一个自动生成的整数)。 Item是产品的名称。价格就是产品的价格。供应商是外键(整数) 我想列出每种商品最便宜的价格和供应商 我对数据库比较陌生,到目前为止,我有以下几点: SELECT Name, MIN(Price), Supplier FROM Supplies GROUP BY Name 这当然给了我一个错误 供应商不在聚合函数或group b

我有一张表,Supplies,列出了不同供应商的产品价格:

| ID | Item | Price | Supplier |
ID是主键(只是一个自动生成的整数)。 Item是产品的名称。价格就是产品的价格。供应商是外键(整数)

我想列出每种商品最便宜的价格和供应商

我对数据库比较陌生,到目前为止,我有以下几点:

SELECT Name, MIN(Price), Supplier FROM Supplies GROUP BY Name
这当然给了我一个错误

供应商不在聚合函数或group by子句中

我做了一些谷歌搜索,阅读了很多关于这个主题的文章和答案,但它们似乎都是针对比我更复杂的情况,让我困惑(正如所说,我对数据库和SQL没有太多经验),或者他们只是谈论错误,而不是如何绕过它


任何帮助都将不胜感激。提前感谢。

在大多数数据库中,您可以使用ANSI标准窗口功能:

select s.*
from (select s.*, min(price) over (partition by item) as minprice
      from supplies
     ) s
where price = minprice;

根据您的RDBMS,您可以使用
ROW_NUMBER()
为每个记录分配一个排名,并首先选择该排名的记录。这比使用额外的联接或相关子查询要快,但目前MySQL不支持这样做

WITH
    sorted_supplies AS
(

    SELECT
        supplies.*,
        ROW_NUMBER() OVER (PARTITION BY name ORDER BY price)   AS price_ordinal
    FROM
        supplies

)
SELECT
    *
FROM
    sorted_supplies
WHERE
    price_ordinal = 1
;
如果不支持
ROW_NUMBER()
,那么您几乎就要走上附加聚合和联接的道路了

SELECT
    supplies.*
FROM
    supplies
INNER JOIN
(
    SELECT
        name,
        MIN(price)   AS min_price
    FROM
        supplies
    GROUP BY
        name
)
    AS min_prices
        ON  min_prices.name      = supplies.name
        AND min_prices.min_price = supplies.price
请注意,如果所有供应商都与最低价格挂钩,则此查询将返回具有相同价格的所有供应商


第一个查询可以通过使用
RANK()
而不是
ROW\u NUMBER()

强制执行,您可以对结果进行排序,然后选择最低/最高级别的项目(基于排序顺序)。假设您使用的是SQL Server 2008或更高版本:

SELECT
    Item, Price, Supplier
FROM (
    SELECT
        ROW_NUMBER() OVER (PARTITION BY Item ORDER BY Price ASC) PriceRank
        , Item
        , Price
        , Supplier
    FROM
        Supplies
    ) supplies_ranked
WHERE
    PriceRank = 1

问题的关键是——如果有多个供应商以完全相同(最低)的价格提供齿轮,该怎么办?那么在结果集中应该返回哪个供应商

实现您所追求的目标的方法是获取最小价格,然后将外部连接返回到同一个表中的product=product和price=price等等。但是,请理解,如果您有上述场景,您将返回两行-每个提供最低价格的供应商一行


自从我开始撰写这篇文章以来,这里出现了3到4个新答案,所以我愿意猜测实际代码已经存在。我将把这篇文章作为“纯英语”的解释留在这里,解释为什么查询不能按您期望的方式工作

如果您没有按划分的
分区(一些sql环境,如Access),那么您也可以这样做:

select s.name, s.supplier, s.price from
(select name, min(price) as min_price from supplies group by name) mp
join supplies s on mp.name=s.name and mp.min_price = s.price 

这远不如按
划分的
有效,因为它有一个子查询,用于查询每个名称的最低价格。注意,如果出现平局,它将返回多个供应商;您可能想要,也可能不想要。

您使用的是哪种RDBMS?如果两个或多个价格相同,是否需要任何平局断路器逻辑?使用HSQLDB。如果两个或两个以上的价格是相同的,我宁愿它显示两个。第二种方法的工程需要。非常感谢您,也感谢您的快速回复。@MatBailie。更合理的做法是,目标是获得每件商品的最低价格,而不是每个供应商的价格。