Een sql-query maken om avg (prijs), min (prijs), max (prijs) samen met avg (volgorde), min (volgorde), max (volgorde) te retourneren

Ik wil graag een SQL-query maken die resultaten samen oplevert voor 2 verschillende query's. Ik wil bijvoorbeeld resultaten hebben in de vorm van: Productnaam, avg (prijs), min (prijs), max (prijs), avg (bestelling), min (bestelling), max (volgorde) Op dit moment heb ik 2 SQL-query's van de vorm:

select 
  product.name, order.id, avg(price), min(price), max(price) 
from 
  product, order 
where
  product.name = order.product_name and product.name = 'price' 
group by 
  product.name, order.id

select 
  product.name, order.id, avg(order), min(order), max(order) 
from 
  product, order 
where 
  product.name = order.product_name and product.name = 'order' 
group by 
  product.name, order.id

Sommige producten hebben een prijs en een bestelling, anderen hebben alleen een prijs en andere hebben alleen en bestellen. Hoe schrijf ik een query waarin alle resultaten worden weergegeven en die worden samengevoegd met degenen die zowel een order als een prijs hebben en die worden weergegeven die beide rijen hebben?

3
Is 'prijs' een productnaam?
toegevoegd de auteur The Nail, de bron
Deze vraag heeft echt tabel aanmaken -instructies en voorbeeldgegevens nodig. De opgegeven vragen zijn eenvoudigweg niet logisch, dus een bepaalde context is hard nodig. Ook zijn, zoals geschreven, deze query's syntactisch ongeldig: order is een gereserveerd woord en kan niet worden gebruikt als een objectnaam tenzij het is ingesloten tussen dubbele aanhalingstekens.
toegevoegd de auteur Allan, de bron

2 antwoord

Ik denk dat je een volledige outer join nodig hebt, omdat rijen zich in de ene tabel of de andere of beide kunnen bevinden:

SELECT 
   NVL(t1.name,t2.name) as name,
   NVL(t1.id, t2.id) as id,
   avg_price,
   min_price,
   max_price,
   avg_order,
   min_order,
   max_order
FROM 
(select product.name, order.id, avg(price) as avg_price, min(price) as min_price, max(price) as max_price 
from product, order 
where product.name = order.product_name and product.name = 'price' 
group by product.name, order.id) t1
FULL OUTER JOIN
(select product.name, order.id, avg(order) as avg_order, min(order) as min_order, max(order) as max_order
from product, order 
where product.name = order.product_name and product.name = 'order' 
group by product.name, order.id) t2
ON t1.name = t2.name
4
toegevoegd
@Dave - zou kunnen zijn, ik weet het niet helemaal zeker. het leek erop dat hij product- en orderintroductie maakte op basis van de productnaam, dus ik neem aan dat dat zijn primaire sleutel was.
toegevoegd de auteur Eric Petroelje, de bron
@Alessandro - Bijwerkt mijn antwoord om op te nemen hoe dat te doen (met NVL om de naam/id te kiezen die niet nul is)
toegevoegd de auteur Eric Petroelje, de bron
Ik vermoed dat je AND t1.id = t2.id wilt toevoegen aan de join-voorwaarde.
toegevoegd de auteur Dave Costa, de bron
Hoe zou ik het zo maken dat product.name & order.id slechts één keer wordt weergegeven en of het niet null is? Op dit moment bevatten de resultaten 2 kolommen voor product.name & 2 voor order.id. In het geval dat 1 nul is, zou ik willen dat de niet-nulwaarde wordt weergegeven. In het geval dat ze hetzelfde zijn, hoeft er slechts 1 te worden weergegeven. Is er een manier om dit te doen?
toegevoegd de auteur Alessandro, de bron

Uw vragen zijn niet erg logisch, dus er is veel dat ik moest proberen af ​​te leiden uit uw vraag. Het is altijd beter om de scripts create table en enkele voorbeeldgegevens (evenals de gewenste uitvoer) te plaatsen bij het stellen van SQL-vragen.

Hieronder staat een scenario dat ik heb gemaakt dat probeert je probleem opnieuw te maken.

CREATE TABLE product(id NUMBER, name VARCHAR2(10));

CREATE TABLE orders(product_name VARCHAR2(10), VALUE NUMBER);

INSERT INTO product
VALUES     (1, 'order');    
INSERT INTO product
VALUES     (1, 'price');    
INSERT INTO product
VALUES     (2, 'order');    
INSERT INTO product
VALUES     (3, 'price');    
INSERT INTO orders
VALUES     ('order', 5);    
INSERT INTO orders
VALUES     ('price', 5);    
COMMIT;

In dit scenario geeft de volgende query drie rijen weer, waarbij de kolommen "order" en/of "prijs" zo nodig zijn ingevuld.

SELECT   p.id,
         AVG(o1.VALUE) as avg_price,
         MIN(o1.VALUE) as min_price,
         MAX(o1.VALUE) as max_price,
         AVG(o2.VALUE) as avg_order,
         MIN(o2.VALUE) as min_order,
         MAX(o2.VALUE) as max_order
FROM             product p
         LEFT JOIN orders o1
              ON p.name = o1.product_name AND p.name = 'price'
         LEFT JOIN orders o2
              ON p.name = o2.product_name AND p.name = 'order'
GROUP BY p.id
0
toegevoegd
Dank je. Ik heb de tabelstructuur eigenlijk vereenvoudigd, maar omdat het niet open source was, moest ik het doen. Dit heeft zeker geholpen.
toegevoegd de auteur Alessandro, de bron