2016-06-05 21 views
5

Zanim ktoś zapyta, tak, jest to część pracy domowej, jednak próbowałem i szukałem podobnych rozwiązań, ale żaden z nich nie zadziałał.Jak wybrać całą krotkę, która ma wartość MAX z podzapytania?

Należy również zauważyć, że powinien on działać na serwerze MySQL, więc należy wziąć pod uwagę każdą specjalną składnię.

Do tego trzeba będzie cztery tabele:

person (idperson INT, firstName VARCHAR(45)) 
beer (idbeer INT, name VARCHAR(45)) 
purchase(idpurchase INT, idperson INT) 
beerxpurchase(idpurchase INT, idbeer INT, quantity INT) 

Gdzie każdy z pierwszych kolumn jest klucz podstawowy wyjątkiem beerxpurchase, który jest kluczowym złożonej z pierwszej i drugiej kolumnie, a wszystkie inne kolumny, które mają wspólne nazwy, reprezentują klucz obcy.

Na koniec muszę utworzyć zapytanie, które zwróci każdą osobę o identyfikatorze piwa, które kupił najwięcej we wszystkich zakupach, oraz o łącznej kwocie tego rodzaju piwa, które kupili.

Zapytanie takie jak:

SELECT person.firstName NAME, beerxpurchase.idBeer BEER, SUM(beerxpurchase.quantity) TOTAL 
FROM person 

INNER JOIN purchase 
on person.idperson = purchase.idperson 

INNER JOIN beerxpurchase 
ON beerxpurchase.idpurchase = purchase.idpurchase 

GROUP BY person.firstName, beerxpurchase.idbeer; 

zwróci całkowitą ilość piwa zakupionego dla każdego konkretnego kodu piwa na osobę, mniej więcej tak:

NAME BEER TOTAL 
A  1  5 
A  2  23 
A  3  3 
A  4  19 
A  5  7 
B  1  11 
B  2  3 
B  3  3 
B  4  4 
B  5  5 
C  3  5 
D  1  8 
D  2  4 
D  4  1 
D  5  10 
E  1  9 
E  4  10 

To, co uważam dobry początek, jednak z tego zapytania powinienem dostać tylko krotkę, która ma maksymalną ilość na użytkownika. Brzmi jak GROUP BY NAME jednak działa coś takiego:

SELECT preferenence.FIRST_NAME, preferenence.ID_BEER, MAX(preferenence.TOTAL_BOUGHT) FROM 
(
    SELECT person.firstName FIRST_NAME, beerxpurchase.idBeer ID_BEER, SUM(beerxpurchase.quantity) TOTAL_BOUGHT 
    FROM person 

    INNER JOIN purchase 
    on person.idperson = purchase.idperson 

    INNER JOIN beerxpurchase 
    ON beerxpurchase.idpurchase = purchase.idpurchase 

    GROUP BY person.firstName, beerxpurchase.idbeer 
) preferenence 

GROUP BY preferenence.FIRST_NAME 
ORDER BY MAX(preferenence.TOTAL_BOUGHT) DESC; 

straci poprawną piwny identyfikator, ale będzie utrzymywać prawidłową nazwę osoby, a całkowitą ilość piwa kupić, coś takiego:

FIRST_NAME  ID_BEER  TOTAL_BOUGHT 
A    1   23 
B    1   11 
D    1   10 
E    1   10 
C    3   5 

Z tego, co przeczytałem, większość DBMS nie śledzi ID_BEER, ponieważ nie jest częścią GRUPY (o ile zrozumiałem). Jednak zmiana ostatniej grupy na GROUP BY preference.FIRST_NAME, preference.ID_BEER zwróci te same krotki z wewnętrznego podzapytania.

Pytanie brzmi: z tego podzapytania, jak można przejść do uzyskania całej krotki powiązanej z tą określoną maksymalną wartością? W przypadku, gdy możesz zaproponować lepsze rozwiązanie dla podzapytania lub zapytania w ogóle, jest to więcej niż mile widziane.

Wszystko, co nie jest do końca jasne lub potrzebujesz więcej informacji o stołach i ich związkach, proszę dać mi znać.

Odpowiedz

1
SELECT p.firstName 
    , b.name beer 
    , m.total 
    FROM 
    (SELECT o.idperson 
      , bo.idbeer 
      , SUM(bo.quantity) total 
     FROM beerxpurchase bo 
     JOIN purchase o 
      ON o.idpurchase = bo.idpurchase 
     GROUP 
      BY o.idperson 
      , bo.idbeer 
    ) m 
    JOIN 
    (SELECT idperson 
      , MAX(total) total 
     FROM 
      (SELECT o.idperson 
        , bo.idbeer 
        , SUM(bo.quantity) total 
       FROM beerxpurchase bo 
       JOIN purchase o 
        ON o.idpurchase = bo.idpurchase 
       GROUP 
        BY o.idperson 
        , bo.idbeer 
      ) x 
     GROUP 
      BY idperson 
    ) n 
    ON n.idperson = m.idperson 
    AND n.total = m.total 
    JOIN person p 
    ON p.idperson = m.idperson 
    JOIN beer b 
    ON b.idbeer = m.idbeer 

http://sqlfiddle.com/#!9/c6bb9/15

wiem, że nie zapytać o nazwę piwa, ale osobiście staram się zamówić piwo o nazwie zamiast id.

+0

To jest w stylu podobnym do odpowiedzi @Mahedi Sabuj, ponieważ używa sprzężenia tego samego podkwerendy, nie? Poza tym, twój też działa, a ty nawet włączyłeś nazwę piwa, jak miło z twojej strony. – Vicyorus

+0

Tak - teraz widzę, że druga odpowiedź miała po prostu kilka błędów - ja, chociaż twierdzę, że moja jest bardziej czytelna ;-) – Strawberry

+0

Nic nie usłyszę ode mnie. – Vicyorus

1

Aby uzyskać beer_id która jest najbardziej zakupione piwo przez osobę, trzeba się do tego procesu: -

  1. Znajdź łączną liczbę piwa każdej kategorii zakupionego przez osobę (co jest już zrobione)
  2. Znajdź maksymalną liczbę piwa z tych kategorii przez osobę (tylko nie licz beer_id)
  3. Dołącz do 1-ki & 2 wynikają z liczby & osoba

Uwaga: Tutaj, ja grupuję się z idperson, ponieważ inna osoba może mieć to samo firstName.

Oto pełna zapytania: -

SELECT person.firstname, personBeer.idbeer, personPurchase.TOTAL_BOUGHT 
FROM 
(
    SELECT purchaseInfo.idperson, MAX(purchaseInfo.TOTAL_BOUGHT) TOTAL_BOUGHT 
    FROM 
    (
     SELECT purchase.idperson, beerxpurchase.idbeer, 
      SUM(beerxpurchase.quantity) TOTAL_BOUGHT 
     FROM purchase 
     INNER JOIN beerxpurchase ON beerxpurchase.idpurchase = purchase.idpurchase 
     GROUP by purchase.idperson, beerxpurchase.idbeer 
    ) purchaseInfo 
    GROUP BY purchaseInfo.idperson 
) personPurchase 
INNER JOIN person ON person.idperson = personPurchase.idperson 
INNER JOIN 
(
    SELECT purchase.idperson, beerxpurchase.idbeer, 
     SUM(beerxpurchase.quantity) TOTAL_BOUGHT 
    FROM purchase 
    INNER JOIN beerxpurchase ON beerxpurchase.idpurchase = purchase.idpurchase 
    GROUP by purchase.idperson, beerxpurchase.idbeer 
) personBeer 
ON personBeer.TOTAL_BOUGHT = personPurchase.TOTAL_BOUGHT 
    AND personBeer.idperson = person.idperson 
ORDER BY personPurchase.TOTAL_BOUGHT DESC 

nadzieję, że to pomaga.

+1

Oto duplikat zapytania, Możemy zarządzać nim przez 'CTE' na' SQL Server'. Ponieważ 'CTE' nie obsługuje' MySQL', dlatego używamy 'sub-zapytania' lub tego samego' pod-zapytania' przez wiele czasu (tj. Dwa razy tutaj), co powoduje, że zapytanie jest duże. –

+0

Sprawdź pisownię dla 'zakupu' i uważam, że wewnętrzne zapytania powinny używać' zakupu' zamiast 'osoby'. W przeciwnym razie jest złoty! Będę go testował, ale wygląda na to, że wykonuję tę pracę. – Vicyorus

Powiązane problemy