【问题标题】:ORA-00979: not a GROUP BY expression with a simple exampleORA-00979: 不是一个简单示例的 GROUP BY 表达式
【发布时间】:2016-06-16 10:00:17
【问题描述】:

我在 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);

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

【问题讨论】:

  • 一般 GROUP BY 规则说:“如果指定了 GROUP BY 子句,则 SELECT 列表中的每个列引用必须标识一个分组列或作为集合函数的参数。”

标签: sql oracle oracle11g group-by ora-00979


【解决方案1】:

您还必须将字段 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

【讨论】:

  • 谢谢你的解释。
【解决方案2】:

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

您可能知道,按a.recipe_id 分组将导致c.recipe_name 的唯一结果(在每个组内)。甲骨文甚至可能也能够获得这些信息。但是 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;

【讨论】:

    【解决方案3】:
    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
    

    【讨论】:

    • 也许你应该试着解释一下为什么这应该有效。
    猜你喜欢
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 2013-03-29
    • 2013-06-25
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多