Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Jak zrobić zapytanie - kolekcja w grze
axeld
post
Post #1





Grupa: Zarejestrowani
Postów: 24
Pomógł: 0
Dołączył: 23.12.2006

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


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ć.
Go to the top of the page
+Quote Post
mariolita
post
Post #2





Grupa: Zarejestrowani
Postów: 116
Pomógł: 10
Dołączył: 24.04.2015

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


  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.  
Go to the top of the page
+Quote Post
axeld
post
Post #3





Grupa: Zarejestrowani
Postów: 24
Pomógł: 0
Dołączył: 23.12.2006

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


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 (IMG:style_emoticons/default/smile.gif)

dzięki raz jeszcze!

Go to the top of the page
+Quote Post
com
post
Post #4





Grupa: Zarejestrowani
Postów: 3 034
Pomógł: 366
Dołączył: 24.05.2012

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


http://stackoverflow.com/questions/854128/...ecords-in-mysql można tak (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
mmmmmmm
post
Post #5





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

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


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;


Ten post edytował mmmmmmm 17.05.2016, 08:34:30
Go to the top of the page
+Quote Post
axeld
post
Post #6





Grupa: Zarejestrowani
Postów: 24
Pomógł: 0
Dołączył: 23.12.2006

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


@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?

Go to the top of the page
+Quote Post
mmmmmmm
post
Post #7





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

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


  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
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 21.10.2025 - 17:57