2016-01-20 6 views
6

Lavorare su un sistema di gestione dell'inventario, e noi abbiamo le seguenti tabelle:Auto partecipare Solo tornando un record

================================================ 
| orders | order_line_items | product_options | 
|--------|-------------------|-----------------| 
| id  | id    | id    | 
| start | order_id   | name   | 
| end | product_option_id |     | 
|  | quantity   |     | 
|  | price    |     | 
|  | event_start  |     | 
|  | event_end   |     | 
================================================ 

sto cercando di calcolare l'inventario in una certa data, quindi ho bisogno di fare un self join per confrontare la quantità su order_line_items con la SOMMA della quantità di altri record in order_line_items con lo stesso product_option_id e dove l'evento di inizio e fine si trova in un intervallo.

Quindi, data una data 2016/01/20, ho:

SELECT order_line_items.id, order_line_items.product_option_id, order_line_items.order_id FROM order_line_items 
WHERE order_line_items.event_end_date >= '2016-01-20 04:00:00' 
AND order_line_items.event_start_date <= '2016-01-21 04:00:00' 
AND order_line_items.product_option_id IS NOT NULL; 

i rendimenti 127 di cui sopra le righe

Quando provo a fare un auto join, in questo modo:

SELECT 
order_line_items.id, 
order_line_items.product_option_id, 
order_line_items.order_id, 
order_line_items.quantity, 

other_line_items.other_product_option_id, 
other_line_items.other_order_id, 
other_line_items.other_quantity, 
other_line_items.total 

FROM order_line_items 

JOIN (
    SELECT 
     id, 
     product_option_id AS other_product_option_id, 
     order_id AS other_order_id, 
     quantity AS other_quantity, 
     SUM(quantity) total 
    FROM order_line_items 
    WHERE order_line_items.event_end_date >= '2016-01-20 04:00:00' 
    AND order_line_items.event_start_date <= '2016-01-21 04:00:00' 
) other_line_items ON order_line_items.product_option_id = other_line_items.other_product_option_id 

WHERE order_line_items.event_end_date >= '2016-01-20 04:00:00' 
AND order_line_items.event_start_date <= '2016-01-21 04:00:00' 
AND order_line_items.product_option_id IS NOT NULL; 

Restituisce solo 1 record. Come si può vedere qui:() ci sono un sacco di record con la stessa product_option_id quindi questa ultima query deve essere restituisce un sacco di righe

+0

Un suggerimento, è necessario rinominare la seconda tabella, perché il sistema può confondere e non è necessario il secondo dove, poiché ne esiste uno nella query secondaria. –

+0

Grazie - rimuovendo il secondo in cui ho ottenuto più record, ma ora tutti i record restituiti hanno lo stesso product_option_id .. strano: https: // goo.gl/itL5bF – Laravelian

+0

ok, prova questo in opzione 'join',' order_id = other_order_id e production_order_id = other_production_order_id' –

risposta

2

La aggiunto SUM(...) trasforma il subquery in una singola riga. Forse il subquery bisogno di avere uno di questi: (. Non so lo schema o l'applicazione abbastanza bene per dire che ha senso)

GROUP BY (id) 
GROUP BY (product_option_id) 
GROUP BY (order_id) 

(Si prega di utilizzare più breve, più distintivi, alias; SQL è molto difficile da leggere a causa della lunghezza e della similarità di order_line_items e other_line_items.)

1

In realtà si desidera ottenere quanto segue? :

SELECT product_option_id, sum(quantity) 
FROM order_line_items 
WHERE event_end_date >= '2016-01-20 04:00:00' 
AND event_start_date <= '2016-01-21 04:00:00' 
GROUP BY 1 

non posso dire perché avete bisogno di un auto join qui

0

E 'difficile dire quello che si vuole, senza risultato di un campione, ma questo vi darà il confronto delle quantità di opzioni di prodotto di ogni ordine di del totale entro il campo:

SELECT oli.order_id, 
     oli.product_option_id, 
     oli.quantity, 
     po.total_quantity 
    FROM order_line_items oli 
    JOIN (
    SELECT product_option_id, 
      SUM(quantity) total_quantity 
     FROM order_line_items 
    WHERE event_end >= '2016-01-20 04:00:00' 
     AND event_start <= '2016-01-21 04:00:00' 
    GROUP BY product_option_id 
     ) po 
    ON po.product_option_id = oli.product_option_id 
WHERE oli.event_end >= '2016-01-20 04:00:00' 
    AND oli.event_start <= '2016-01-21 04:00:00' 

Se è possibile avere più righe dello stesso product_option in un ordine potrebbe essere necessario modificare questo come modo:

SELECT oli.order_id, 
     oli.product_option_id, 
     SUM(oli.quantity) order_quantity, 
     po.total_quantity 
    FROM order_line_items oli 
    JOIN (
     SELECT product_option_id, 
      SUM(quantity) total_quantity 
     FROM order_line_items 
     WHERE event_end >= '2016-01-20 04:00:00' 
     AND event_start <= '2016-01-21 04:00:00' 
    GROUP BY product_option_id 
     ) po 
     ON po.product_option_id = oli.product_option_id 
    WHERE oli.event_end >= '2016-01-20 04:00:00' 
    AND oli.event_start <= '2016-01-21 04:00:00' 
GROUP BY oli.order_id, 
     oli.product_option_id 
0

Da quello che ho capito, in realtà dovrebbe essere lasciato unire il orders e il product_options alla tabella order_line_items.

La query dovrebbe essere simile a questa, per la quantità di articoli sugli ordini tra determinate date.

SELECT product_options.id, production_options.name, SUM(order_line_items.quantity) 
FROM order_line_items 
LEFT JOIN product_options ON production_options.id=order_line_items.product_option_id 
LEFT JOIN orders ON orders.id=order_line_items.order_id 
WHERE orders.start>='SOME DATETIME' AND orders.end<='SOME DATETIME' 
GROUP BY product_options.id 

Inoltre, solo un commento, product_options dovrebbe probabilmente solo essere nominato products. Nomi dei tavoli più brevi per la vittoria!

+0

Ho solo pensato di più sui buoni nomi delle tabelle. Vorrei andare con 'order',' item' e 'order_item'. – fiddlestacks

Problemi correlati