2016-03-03 8 views
6

ho provato il seguente esempio in Oracle 11g: http://joshualande.com/filters-joins-aggregations/ORA-00979: non un GROUP BY espressione con un semplice esempio

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; 

ottengo l'errore SQL: ORA-00979: not a GROUP BY expression...

Le tabelle utilizzate nella query sono i seguenti:

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

So che questa domanda è stata posta diverse volte già, ma mi spiegano attraverso questo esempio.

+0

gruppo Generale BY regola dice: "Se non viene specificata una clausola GROUP BY, ogni riferimento di colonna nell'elenco SELECT deve o identificare una colonna di raggruppamento o essere argomento di una funzione impostata. " – jarlh

risposta

4

nella clausola SELECT, si può fare riferimento solo alle espressioni che o appaiono nella clausola GROUP BY o sono aggregazioni (come SUM). c.recipe_name non si qualifica come tale.

È possibile sapere che il raggruppamento per a.recipe_id porterà a un risultato univoco per c.recipe_name (all'interno di ciascun gruppo). E Oracle potrebbe anche essere in grado di ricavare anche queste informazioni. Ma SQL è più severo e richiede di inserire l'espressione nella clausola GROUP BY.

Quindi, basta scrivere:

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; 
+0

Grazie per aver spiegato. Adesso è tutto chiaro. – dsz36

3

Devi mettere anche campo c.recipe_name nella clausola 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; 

Il problema con la query è che una colonna non aggregata, come c.recipe_name, appare nella clausola SELECT.

uscita:

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

Thx per la spiegazione. – dsz36

0
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 
+0

Forse dovresti provare a spiegare perché questo dovrebbe funzionare. – Cyclonecode