ORA-00979: 不是 GROUP BY 表达式用一个简单的例子

ORA-00979: not a GROUP BY expression with a simple example

我在 Oracle 11g 中尝试了以下示例:http://joshualande.com/filters-joins-aggregations/

SELECT c.recipe_name, 
COUNT(a.ingredient_id), 
SUM(a.amount*b.ingredient_price)
FROM recipe_ingredients a
JOIN ingredients b
ON a.ingredient_id = b.ingredient_id
JOIN recipes c
ON a.recipe_id = c.recipe_id
GROUP BY a.recipe_id;

我收到 SQL 错误:ORA-00979: not a GROUP BY expression...

查询中使用的表如下:

CREATE TABLE recipes (
  recipe_id INT NOT NULL,
  recipe_name VARCHAR(30) NOT NULL,
  PRIMARY KEY (recipe_id),
  UNIQUE (recipe_name)
);

INSERT INTO RECIPES (RECIPE_ID, RECIPE_NAME) VALUES (1, 'Tacos');
INSERT INTO RECIPES (recipe_id, recipe_name) VALUES (2, 'Tomato Soup');
INSERT INTO RECIPES (recipe_id, recipe_name) VALUES (3, 'Grilled Cheese');

CREATE TABLE ingredients (
  ingredient_id INT NOT NULL, 
  ingredient_name VARCHAR(30) NOT NULL,
  ingredient_price INT NOT NULL,
  PRIMARY KEY (ingredient_id),  
  UNIQUE (ingredient_name)
);

INSERT INTO ingredients (ingredient_id, ingredient_name, ingredient_price) VALUES (1, 'Beef', 5);
INSERT INTO ingredients (ingredient_id, ingredient_name, ingredient_price) VALUES (2, 'Lettuce', 1);
INSERT INTO ingredients (ingredient_id, ingredient_name, ingredient_price) VALUES (3, 'Tomatoes', 2);
INSERT INTO ingredients (ingredient_id, ingredient_name, ingredient_price) VALUES (4, 'Taco Shell', 2);
INSERT INTO ingredients (ingredient_id, ingredient_name, ingredient_price) VALUES (5, 'Cheese', 3);
INSERT INTO ingredients (ingredient_id, ingredient_name, ingredient_price) VALUES (6, 'Milk', 1);
INSERT INTO ingredients (ingredient_id, ingredient_name, ingredient_price) VALUES (7, 'Bread', 2);

CREATE TABLE recipe_ingredients (
  recipe_id int NOT NULL, 
  ingredient_id INT NOT NULL, 
  amount INT NOT NULL,
  PRIMARY KEY (recipe_id,ingredient_id)
);

INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (1,1,1);
INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (1,2,2);
INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (1,3,2);
INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (1,4,3);
INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (1,5,1);
INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (2,3,2);
INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (2,6,1);
INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (3,5,1);
INSERT INTO recipe_ingredients (recipe_id, ingredient_id, amount) VALUES (3,7,2);

我知道这个问题已经被问过好几次了,但请通过这个例子向我解释一下。

您还必须将字段 c.recipe_name 放在 GROUP BY 子句中:

SELECT c.recipe_name, 
       COUNT(a.ingredient_id) AS cnt, 
       SUM(a.amount*b.ingredient_price) AS sum
FROM recipe_ingredients a
JOIN ingredients b
  ON a.ingredient_id = b.ingredient_id
JOIN recipes c
  ON a.recipe_id = c.recipe_id
GROUP BY c.recipe_name, a.recipe_id;

您的查询的问题在于 c.recipe_name 等非聚合列出现在 SELECT 子句中。

输出:

recipe_name     cnt sum
------------------------
Grilled Cheese  2   7
Tacos           5   20
Tomato Soup     2   5

在SELECT子句中,只能引用出现在GROUP BY子句中或者是聚合(如SUM)的表达式。 c.recipe_name 不符合条件。

您可能知道按 a.recipe_id 分组会导致 c.recipe_name 的唯一结果(在每个组内)。 Oracle 甚至可能也能够导出此信息。但 SQL 更严格,要求您将表达式放在 GROUP BY 子句中。

所以,写:

SELECT c.recipe_name, 
    COUNT(a.ingredient_id), 
    SUM(a.amount*b.ingredient_price)
FROM recipe_ingredients a
JOIN ingredients b
    ON a.ingredient_id = b.ingredient_id
JOIN recipes c
    ON a.recipe_id = c.recipe_id
GROUP BY a.recipe_id, c.recipe_name;
SELECT 
    c.recipe_name, 
    COUNT(a.ingredient_id), 
    SUM(a.amount*b.ingredient_price)
FROM recipe_ingredients a
JOIN ingredients b
  ON a.ingredient_id = b.ingredient_id
JOIN recipes c
  ON a.recipe_id = c.recipe_id
GROUP BY c.recipe_name