Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Jak zrobić zapytanie - kolekcja w grze
Forum PHP.pl > Forum > Bazy danych > MySQL
axeld
Witam!

Mam taki problem, którego nie potrafiłem wyszukać w googlach ze względu na jego specyficzną naturę.
Otóż piszę grę, w której uzupełnia się kolekcję. Przedmioty do kolekcji dostajemy losowo i jest ich 100 różnych.
Chciałbym, aby gracze mogli się wymieniać przedmiotami, które mają podwójne.

Tabela KOLEKCJA jest prosta:

kol_id INT
user_id INT
przedmiot_id INT
na_wymianie TINYINT (przyjmuje 0 lub 1)

Kiedy gracz ma więcej niż 1 ten sam przedmiot, może jeden z nich wystawić na wymianę, wtedy na_wymianie=1
I na tej wymianie jest, dla uproszczenia, tylko 1 wystawiony przedmiot.

Ja teraz jako gracz wchodzę na wymianę i widzę ten przedmiot na liście.
I tu pojawia się select, którego nie potrafię napisać, czyli:

POKAŻ MI LISTĘ MOICH PRZEDMIOTÓW, KTÓRYCH MAM WIĘCEJ NIŻ 1 i GRACZ Z WYMIANY ICH NIE MA.

Wtedy decyduję który przedmiot chcę wymienić za ten którego ja pożądam i tyle...


Pomóżcie napisać tego selecta, albo chociaż nakierujcie w jaki sposób to napisać.

pozdrawiam i z góry dzięki!
Adam

PS. Acha! Tak dla jasności. Gra jest online i jest całkowicie darmowa. Jeśli ktoś jest zainteresowany to podeślę adres, bo nie wiem czy tu na forum można się reklamować.
mariolita
  1. include("serwer.php");
  2.  
  3. $arrayMojePrzedmiotyPowtarzajaceSie = array();
  4.  
  5. $arrayPrzedmiotyGraczaPowtarzajaceSie= array();
  6.  
  7.  
  8. $selectMojePrzedmioty = "SELECT * FROM mojeprzedmioty";
  9.  
  10. $selectMojePrzedmioty = $conn->query($selectMojePrzedmioty);
  11.  
  12. if ($selectMojePrzedmioty->num_rows > 0) {
  13.  
  14. while($row = $selectMojePrzedmioty->fetch_assoc()) {
  15.  
  16. if($row["ilosc"] > 1) {
  17.  
  18. // UMIEŚĆ W TABLICY //
  19.  
  20. }
  21.  
  22. }
  23.  
  24. }
  25.  
  26. $selectGraczaPrzedmioty = "SELECT * FROM graczaprzedmioty";
  27.  
  28. $selectGraczaPrzedmioty = $conn->query($selectGraczaPrzedmioty);
  29.  
  30. if ($selectGraczaPrzedmioty->num_rows > 0) {
  31.  
  32. while($row = $selectGraczaPrzedmioty->fetch_assoc()) {
  33.  
  34. if($row["ilosc"] > 1) {
  35.  
  36. // UMIEŚĆ W TABLICY //
  37.  
  38. }
  39.  
  40. }
  41.  
  42. }
  43.  
  44. // W TEN SPOSÓB MASZ DWIE TABLICE - JEDNĄ Z PRZEDMIOTAMI KTÓRYCH TY MASZ WIĘCEJ NIŻ JEDNEN I DRUGĄ TABLICE GRACZ Z PRZEDMIOTAMI KTORYCH MA WIĘCEJ NIŻ JEDEN //
  45.  
  46. // DALEJ PORÓWNUJESZ CO KTÓRY/NIE MA //
  47.  
  48. // O TO CHODZI?questionmark.gif //
axeld
Dzięki!

Myślałem, że będę musiał polegać na jakimś skomplikowanym selekcie w mysql, ale podsunąłeś/ęłaś mi świetny pomysł z tymi tablicami.

Jeszcze nie zacząłem pisać ale pomysł jest taki:

1. tworzę tablicę z wszystkimi stoma elementami (1, 2, 3, 4, 5, 6.........99, 100)
2. z tej tablicy wyrzucam przedmioty, które on ma = zostają tam tylko przedmioty, których nie ma
3. robię sobie tablicę z moimi podwójnymi elementami
4. porównuję czy w mojej tablicy są jakieś przedmioty zawierające się w jego tablicy.
5. wymiana smile.gif

dzięki raz jeszcze!

mmmmmmm
SQLFiddle wysiadło, więc masz tu dwa zapytania, ktore to robia..
Musisz sobie sprawdzic, ktore dla twoich warunkow bedzie wydajniejsze...
  1. USE test;
  2. DROP TABLE IF EXISTS kolekcja;
  3.  
  4. CREATE TABLE kolekcja(
  5. kol_id INT AUTO_INCREMENT PRIMARY KEY,
  6. user_id INT NOT NULL ,
  7. przedmiot_id INT NOT NULL,
  8. na_wymianie TINYINT DEFAULT 0,
  9. INDEX(user_id, przedmiot_id));
  10.  
  11. INSERT INTO kolekcja(user_id, przedmiot_id) VALUES
  12. -- moje przedmioty
  13. (1, 1),
  14. (1, 2),
  15. (1, 3),
  16. (1, 2), -- dubel
  17. (1, 4),
  18. (1, 5),
  19. (1, 1), -- dubel
  20. (1, 2), -- dubel
  21. (1, 5), -- dubel
  22. (1, 6);
  23.  
  24. INSERT INTO kolekcja(user_id, przedmiot_id) VALUES
  25. -- jego przedmioty
  26. (2, 1),
  27. (2, 2),
  28. (2, 3);
  29.  
  30.  
  31.  
  32. SELECT
  33. przedmiot_id
  34. FROM
  35. kolekcja k
  36. WHERE
  37. k.user_id=1
  38. AND przedmiot_id NOT IN (SELECT przedmiot_id FROM kolekcja WHERE user_id=2)
  39. GROUP BY
  40. przedmiot_id
  41. HAVING count(*)>1;
  42.  
  43.  
  44.  
  45. SELECT
  46. k.przedmiot_id
  47. FROM
  48. kolekcja k
  49. LEFT JOIN
  50. kolekcja o
  51. ON o.user_id=2 AND o.przedmiot_id=k.przedmiot_id
  52. WHERE
  53. k.user_id=1
  54. AND o.przedmiot_id IS NULL
  55. GROUP BY
  56. k.przedmiot_id
  57. HAVING count(*)>1;
axeld
@mmmmmmmm
To jest dokładnie to czego szukałem!
Działa wyśmienicie!

Dzięki po stokroć!

Jeszcze raz ja.
Bardzo dziwna sprawa wyniknęła.
Z tymi itemami do kolekcji mam taką tabelę

  1. ki_id INT PRIMARY AUTO_INCREMENT
  2. ki_userid INT
  3. ki_przedmiotid INT


Do tej tabelki wrzucają się rekordy jeśli jakiś user znajdzie przedmiot.
Chciałem ułożyć zapytanie, które wybiera mi wszystkich userów bez powtórzeń, którzy mają jakiekolwiek duplikaty i nie są zalogowanym userem.

Wymyśliłem takie zapytanie:

  1. SELECT ki_userid aa
  2. FROM astro_kolekcja_itemy
  3. WHERE
  4. (SELECT ki_przedmiotid FROM astro_kolekcja_itemy WHERE ki_userid = aa GROUP BY ki_przedmiotid HAVING COUNT(*)>1 LIMIT 1)
  5. AND ki_userid<>'$uzytkownik_zalogowany'
  6. GROUP BY ki_userid ORDER BY rand()


i działało bardzo dobrze.

Ale... postanowiłem założyć indexy na pola ki_userid i ki_przedmiotid i zapytanie to całkiem przestało działać - zawsze zwracało pusty wynik.
Ktoś wytłumaczy?

Założyłem też indexy w innych tabelach i teraz zaczynam się martwić.

Z góry dziękuję!



--------------

Nie dawało mi to spokoju i wymęczyłem nowe zapytanie:
  1. SELECT DISTINCT ki_userid
  2. FROM astro_kolekcja_itemy
  3. WHERE ki_userid <>'$uzytkownik_zalogowany'
  4. GROUP BY ki_userid, ki_przedmiotid
  5. HAVING COUNT( ki_przedmiotid ) >1

Działa tak samo ale jest prostsze i indexy znów działają!
Mógłby ktoś jednak wyjaśnić dlaczego do tego poprzedniego zapytania z indexami nie działało?

mmmmmmm
  1. SELECT ki_userid aa
  2. FROM astro_kolekcja_itemy
  3. WHERE
  4. (SELECT ki_przedmiotid FROM astro_kolekcja_itemy WHERE ki_userid = aa GROUP BY ki_przedmiotid HAVING COUNT(*)>1 LIMIT 1)
  5. AND ki_userid<>'$uzytkownik_zalogowany'
  6. GROUP BY ki_userid ORDER BY rand()

Nie wiem, co ten SELECT we WHERE miałby robić. Nie znam żadnej sytuacji (a pracuje z bazami parę ładnych lat), w której trzeba by było czegoś takiego użyć.
  1. SELECT DISTINCT ki_userid
  2. FROM astro_kolekcja_itemy
  3. WHERE ki_userid <>'$uzytkownik_zalogowany'
  4. GROUP BY ki_userid, ki_przedmiotid
  5. HAVING COUNT( ki_przedmiotid ) >1

To jest skopane całkowicie.
DISTINCT + GROUP = źle
GROUP BY ki_przedmiotid + HAVING COUNT(ki_przedmiotid) = źle
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.