使用GROUPY BY获取其最昂贵产品的名称和价格

时间:2017-07-16 07:26:56

标签: sql postgresql

这是我的表:

CREATE TABLE Manufacturers (
    Code          integer PRIMARY KEY,
    Name          text
);
CREATE TABLE Products (
    Code          integer PRIMARY KEY,
    Name          text,
    Price         real,
    Manufacturer  integer REFERENCES Manufacturers (Code)
);

我想选择每个制造商的名称以及最昂贵产品的名称和价格。

我在Postgresql9.6中尝试这个

SELECT A.Name, A.Price, F.Name
    FROM Products A INNER JOIN Manufacturers F
    ON A.Manufacturer = F.Code
    AND A.Price =
    (
      SELECT MAX(A.Price)
      FROM Products A
      WHERE A.Manufacturer = F.Code
    );

完成它需要永远。

然后我试试这个:

SELECT Manufacturers.Name AS ManufacturersName, MAX(Price), Products.Name
  FROM Products, Manufacturers
  WHERE Products.Manufacturer = Manufacturers.Code
  GROUP BY Manufacturers.Name;

我收到了错误:

ERROR:  column "products.name" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...ufacturers.Name AS ManufacturersName, MAX(Price), Products.N...

我知道products.name不应出现在其中,但它是postgresql的约束吗?

我在结果中需要products.name,有人可以指出我正确的方向吗?

2 个答案:

答案 0 :(得分:1)

以下查询将为每个制造商的产品提供最昂贵的价格。如果出现平局,它将返回多个产品。如果您只想为每个制造商生产一种产品,而不是平局,请将DENSE_RANK替换为ROW_NUMBER

SELECT
    t.m_name,
    t.p_name,
    t.Price
FROM
(
    SELECT
        t1.Name AS m_name,
        COALESCE(t2.Name, 'NA') AS p_name,
        COALESCE(t2.Price, 0.0) AS price,
        DENSE_RANK() OVER (PARTITION BY t1.Code ORDER BY t2.Price DESC) dr
    FROM Manufacturers t1
    LEFT JOIN Products t2
        ON t1.Code = t2.Manufacturer
) t
WHERE t.dr = 1;

答案 1 :(得分:1)

您可以使用DISTINCT ON

SELECT DISTINCT ON (m.Name) m.Name AS ManufacturersName, p.Price, p.Name
FROM Products p JOIN
     Manufacturers m
     ON p.Manufacturer = m.Code
ORDER BY m.Name, p.Price DESC;

似乎没有必要进行汇总。