使用select和group by的简单SQL查询

时间:2012-11-11 17:59:24

标签: sql sql-server tsql select group-by

我有一些问题需要理解。

我有下一张桌子:

ID  PROD    PRICE
1   A        10
2   B        20
3   C        30
4   A        1
5   B        12
6   C        2
7   A        7
8   B        8
9   C        9
10  A        5
11  B        2

我想获得所有产品的所有最低价格,这意味着我希望获得3条记录,即每个产品的最低价格。 从上面的例子中,这是我想要的:

ID  PROD    MIN(PRICE)
4   A       1
11  B       2
6   C       2

这是我写的查询:

select id, prod, min(price)
from A1
group by(prod);

但这是我得到的记录:

ID  PROD    MIN(PRICE)
1   A        1
2   B        2
3   C        2

正如您所看到的,ID值是错误的,它只给我一些行计数器,而不是实际的ID值。

您可以在下一个link

查看

我做错了什么?

2 个答案:

答案 0 :(得分:7)

SELECT  a.*
FROM    A1 a
        INNER JOIN
        (
            SELECT Prod, MIN(Price) minPrice
            FROM A1
            GROUP BY Prod
        ) b ON a.Prod = b.Prod AND
                a.Price = b.minPrice

MSSQL

SELECT ID, Prod, Price
FROM
(
  SELECT ID, Prod, Price,
        ROW_NUMBER() OVER(Partition BY Prod ORDER BY Price ASC) s
  FROM A1
) a
WHERE s = 1

答案 1 :(得分:1)

您必须使用MySQL或PostgreSQL。

在标准SQL中,必须在GROUP BY子句中引用select-list中的所有非聚合列。

我不清楚您是否需要ID列。如果没有,请使用:

SELECT prod, MIN(price) AS min_price
  FROM A1
 GROUP BY prod;

如果您需要匹配的ID号,那么这将成为子查询:

SELECT id, prod, price
  FROM A1
  JOIN (SELECT prod, MIN(price) AS min_price
          FROM A1
         GROUP BY prod
       ) AS A2 ON A1.prod = A2.prod AND A1.price = A2.min_price;

  

您能否解释一下我写的内容有什么问题,是的,我需要ID栏。

select id, prod, min(price)
from A1
group by(prod);

在标准SQL中,您将收到一条错误消息(或者,如果不是标准的话,在大多数SQL DBMS中)。

如果允许您从GROUP BY子句中省略ID列,那么您将获得正确的prodMIN(price)值的ID的准随机值。基本上,优化器将根据其奇思妙想选择它所知道的任何方便的ID。具体来说,它不执行子查询并加入完整答案。例如,它可能会执行顺序扫描,并且它返回的ID可能是它遇到的给定prod值的第一个或最后一个,或者它可能是其他值 - 我甚至不确定prod = 'A'返回的ID是否必须是与prod = 'A'相关联的ID;你必须仔细阅读本手册。基本上,您的查询是不确定的,因此许多返回值是允许的和“正确的”(但不是您想要的)。

请注意,如果按ID分组而不是prod,那么prod中的结果将是确定的。这是因为ID列是表的候选键(唯一标识符)。 (我相信PostgreSQL区分了这两种情况 - 但我不确定; MySQL没有。)