2016-01-20 12 views
6

Praca w systemie zarządzania zapasami, a mamy następujące tabele:Własna dołączyć tylko jeden rekord powrocie

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

próbuję obliczyć inwentaryzacji w określonym terminie, więc muszę zrobić własny przyłączyć porównywanie ilości na order_line_items z SUM z ilością innych rekordów w order_line_items z tym samym product_option_id, i gdzie początek i koniec zdarzenia są w zakresie.

więc, biorąc pod uwagę datę 20.01.2016, mam:

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; 

Powyższe zwraca 127 wierszy

Kiedy próbuję zrobić własny dołączyć, tak:

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; 

Powoduje tylko zwrot 1 rekordu. Jak widać tutaj:() istnieje wiele rekordów z tym samym product_option_id więc to ostatnie zapytanie należy powracającego dużo wierszy

+0

Sugestia, należy zmienić nazwę drugiej tabeli, ponieważ system może mylić i nie potrzebować drugiego miejsca, w którym jest, ponieważ masz go w sub zapytania. –

+0

Dzięki - usunięcie drugiego, w którym dostałem więcej rekordów, ale teraz wszystkie zwrócone rekordy mają ten sam product_option_id .. weird: https: // goo.gl/itL5bF – Laravelian

+0

ok, spróbuj tego w opcji 'join',' order_id = other_order_id i production_order_id = other_production_order_id' –

Odpowiedz

2

dodanego SUM(...) włącza podzapytania w jednym rzędzie. Może podkwerendę musiał mieć jedną z nich: (. Nie mam schematu lub aplikacji na tyle dobrze, aby powiedzieć, co ma sens)

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

(proszę użyć krótsze, bardziej wyrazisty, pseudonimy; SQL jest bardzo trudny do odczytania ze względu na długość i podobieństwo order_line_items i other_line_items.)

1

Czy rzeczywiście chcesz uzyskać następujące? :

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 

nie mogę powiedzieć dlaczego trzeba ja przyłączyć tutaj

0

Trudno powiedzieć, co chcesz bez wyniku próbki, ale to daje porównanie ilości opcji produktowych każdego zamówienia do całkowita w zakresie:

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' 

Jeśli można mieć wiele wierszy o tej samej product_option w kolejności może trzeba dostosować to tak jak:

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

Z tego co rozumiem, należy faktycznie dołączyć do tabeli orders i product_options do tabeli order_line_items.

Twoje zapytanie powinno wyglądać mniej więcej tak samo, jak ilość pozycji w zamówieniach między określonymi datami.

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 

Również tylko komentarz, product_options prawdopodobnie powinien być nazwany tylko products. Krótsze nazwy stołów do wygrania!

+0

Po prostu pomyślałem o dobrych nazwach stołów. Wybrałbym 'order',' item' oraz 'order_item'. – fiddlestacks