Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Aukcje - zapytanie SELECT
markonix
post 28.06.2011, 15:42:42
Post #1





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Struktura bazy w uproszczonym schemacie:
tabela `list` czyli tabela główna z opisem aukcji, wystawcą, datą zakończenia itp.
tebela `bids` czyli tabela z poszczególnymi licytacjami (kwota, użytkownik).
Relacja jeden do wielu (jedna aukcja, 0-* licytacji).


  1. SELECT * FROM `auctions_list` AS `fr` LEFT JOIN
  2. (
  3. SELECT `auction_id`, `username`, COUNT(*) AS `bidsum`, MAX(`bid_value`) AS `maxbid`
  4. FROM `auctions_bids` WHERE `status` = 1 GROUP BY `auction_id`
  5. ) AS `fm`
  6. ON fr.id = fm.auction_id
  7. WHERE ORDER BY `date_end` DESC

Zapytanie kolejno bierze listę aukcji, następnie dołącza do niej na podstawie ID licytacje.
Bez problemu działa podsumowanie tj. maksymalny bid, liczba licytacji.
Potem oczywiście za WHERE jest troszkę więcej warunków ale nie chce zaciemniać.

Problem jest jak na razie jeden - `username` NIE zawiera nicku osoby, która wygrywa.
Bierze pierwszy lepszy nick z listy bidów dla danej aukcji.
Nie ma możliwości zastosowania ORDER BY, które jest blokowane przez grupowanie.
Gdy zaś nie ma grupowania to liczy sumę bidów i maksymalny bid globalnie, a nie dla danej aukcji.

Wynik ma mniej więcej wyglądać następująco:

Tytuł aukcji || Sprzedawca || Liczba ofert || Najwyższa oferta || Wygrywa (pogrubione = z tabeli bids)

Działa wszystko oprócz ostatniego, ogólnie zapytanie się strasznie rozrasta (dochodzą warunki dotyczące aukcji, bidów, sortowanie).
Zastanawiam się czy nie robię tego troszkę naokoło.
Nie ukrywam, że wynik ma być zbliżony od listy aukcji jak z Allegro (oprócz paginacji).

Ten post edytował markonix 28.06.2011, 15:45:49


--------------------
Go to the top of the page
+Quote Post
Magic WWW
post 28.06.2011, 22:45:07
Post #2





Grupa: Zarejestrowani
Postów: 123
Pomógł: 32
Dołączył: 9.09.2010
Skąd: Brzeg

Ostrzeżenie: (0%)
-----


Pokaż mi struktury tych wszystkich użytych tabel, inaczej nie mogę Ci pomów wink.gif
Go to the top of the page
+Quote Post
markonix
post 29.06.2011, 13:49:54
Post #3





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Raczej nic nie pomogą, są tam tylko atrybuty aukcji, które nie mają znaczenie dla problemu.
A tabela bidów składa się w uproszczonej formie z id aukcji (do łączenia), użytkownika i kwoty.

Po polsku pytanie brzmi - jak stworzyć listę aukcji w relacji 1 do 1 gdzie wygląda to tak:
AUKCJA + WIERSZ NAJWIĘKSZEGO BIDA DLA AUKCJI. (największa wartość w określonej kolumnie)


--------------------
Go to the top of the page
+Quote Post
thek
post 29.06.2011, 14:52:20
Post #4





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Powiem tak... Mysql teoretycznie pobiera losowy wiersz spośród tych zgrupowanych. W praktyce jednak jest ciut inaczej. Ten losowy to pierwszy spośród grupy. Efekt? Posortuj rekordy według wysokości bid malejąco w podzapytaniu, zanim zaczniesz joinować i grupować. Count i max będą działać, ale dodatkowo będziesz miał tabelę bidów tak posortowaną, że zawsze pierwszy w grupie będzie bid z najwyższą ofertą. A tym samym będzie w nim na bank klucz do id usera, który go walnął.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
markonix
post 29.06.2011, 15:40:56
Post #5





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Niestety ORDER BY w tym podzapytaniu nie zadziała - posortuje WYNIK grupowania, a nie bidy w danej grupie.
No chyba, że mam to jeszcze inaczej zrobił, 3 select w tym selectcie smile.gif


--------------------
Go to the top of the page
+Quote Post
rollen
post 29.06.2011, 21:41:07
Post #6





Grupa: Zarejestrowani
Postów: 16
Pomógł: 6
Dołączył: 24.06.2011

Ostrzeżenie: (0%)
-----


A może tak...

  1. SELECT * FROM `auctions_list` AS `fr` LEFT JOIN
  2. ( SELECT stat.*, ab.username FROM
  3. (SELECT `auction_id`, COUNT(*) AS `bidsum`, MAX(`bid_value`) AS `maxbid`
  4. FROM `auctions_bids` WHERE `status` = 1 GROUP BY `auction_id`) AS stat JOIN auctions_bids ab ON stat.auction_id = ab.auction_id
  5. ) AS `fm`
  6. ON fr.id = fm.auction_id
  7. WHERE ORDER BY `date_end` DESC
Go to the top of the page
+Quote Post
thek
post 29.06.2011, 21:55:01
Post #7





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




@Markonix: Pisałem wyraźnie... posortuj wcześniej wink.gif
  1. SELECT t.* FROM tabela1 AS t1 LEFT JOIN ( SELECT * FROM inna ORDER BY kolumna DESC) AS t2 ON t1.kolumna = t2.kolumna2 GROUP BY t1.kolumna3

Jak się nie da, jak się da smile.gif


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
markonix
post 30.06.2011, 20:25:19
Post #8





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Zwraca wynik 1 aukcja -> wszystkie leady.
Ogólnie to w skrypcie poszedłem na skróty i dodałem te drugie zapytanie.
Myślę też o tym, aby właśnie napisać takie zapytanie jak Twoje, albo po prostu zwykłego JOINa + bidy posortowanego wg wartości.
Wtedy jednak zwracam gdzieś o 500% więcej wierszy niż potrzebuje oraz wymagana jest obróbka w PHP (wyświetlać tylko po jednym wierszu na id aukcji).

EDIT:

  1. SELECT s1.auction_id, s1.username, s1.bid_value, s3.*
  2. FROM `auctions_bids` s1
  3. LEFT JOIN `auctions_bids` s2 ON ( s1.auction_id = s2.auction_id
  4. AND s1.bid_value < s2.bid_value )
  5. LEFT JOIN `auctions_list` s3 ON ( s1.auction_id = s3.id )
  6. WHERE s2.auction_id IS NULL


http://dev.mysql.com/doc/refman/5.0/en/exa...-group-row.html

Coś tam mi wyszło ale jeszcze będę testował smile.gif

Ten post edytował markonix 30.06.2011, 20:26:39


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 04:09