Witamy na GTAOnline Obecny czas to 2018-11-14, 09:40 Użytkowników: 76674
Strona główna | Użytkownicy | Grupy | Faq | Regulamin | Zaloguj

Poprzedni temat :: Następny temat
[MYSQL] Pobieranie dzielnic gangowych i respektu
Autor Wiadomość

KacperCL 





Informacje
Nick w MP: [FS]Kacper[C]
Wiek: 19
Na forum: 2649 dni
Posty: 16
Respekt: 60

Wysłany: 2017-12-20, 21:57   [MYSQL] Pobieranie dzielnic gangowych i respektu



Witam.

Mamy 3 tabele: gangs, zones, zones_gangscore.

Struktura tabeli gangs:

Kod:


CREATE TABLE `gangs` (
`id` smallint(1) UNSIGNED NOT NULL,
`color` char(6) NOT NULL DEFAULT '000000'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `gangs`
ADD PRIMARY KEY (`id`);


Struktura tabeli zones:

Kod:

CREATE TABLE `zones` (
`id` int(10) UNSIGNED NOT NULL,
`miny` double NOT NULL,
`minx` double NOT NULL,
`maxy` double NOT NULL,
`maxx` double NOT NULL,
`active` tinyint(3) UNSIGNED NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `zones`
ADD PRIMARY KEY (`id`);


Struktura tabeli zones_gangscore
Kod:


CREATE TABLE `zones_gangscore` (
`id_zone` int(10) UNSIGNED NOT NULL,
`id_gang` smallint(5) UNSIGNED NOT NULL,
`respect` int(10) UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `zones_gangscore`
ADD PRIMARY KEY (`id_zone`,`id_gang`),
ADD KEY `respect` (`respect`);


W gangs mamy przykładowe 2 gangi:
ID=1, color FFFFFF
ID=2 color FFFF00

W zones mamy przykładową strefę:
id= 34 miny=1785.03 minx=-2259.5 maxy=1981.03 maxx=2063.5 active=1

W zones_gangscore, tabeli która odpowiada za "respekt" dzielnicy. Gangi zdobywają dzielnicę, poprzez przebywanie na niej. Jedna minuta przebywania na dzielnicy powoduje zwiększenie respektu o 1. Przykładowo Gang 1 przebywa na dzielnicy 10 minut, ma 10 respektu. Gang 2 przebywa 5 minut, ma 5 respektu. Przykład w zones_gangscore
id_zone=34 id_gang=2 respect=5
id_zone=34 id_gang=1 respect=10

Mamy zapytanie SQL:
Kod:

SELECT * FROM (select z.id,z.miny,z.minx,z.maxy,z.maxx,IFNULL(g.color,'909090') from zones z LEFT JOIN zones_gangscore zgs ON zgs.id_zone=z.id LEFT JOIN gangs g ON g.id=zgs.id_gang WHERE z.active=1 ORDER BY zgs.respect DESC) s1 GROUP BY id LIMIT 60;


Zwraca:
Kod:

id miny minx maxy maxx IFNULL(g.color,'909090')
34 1785.03 -2259.5 1981.03 -2063.5 FFFF00


Zapytanie ma pobrać dzielnice gangowe oraz gang, który w tej dzielnicy "zarobił" najwięcej respektu. Jak pisałem wyżej, Gang 1 (kolor #FFFFFF) ma 10 respektu, a gang 2 (kolor #FFFF00) ma 5 respektu. Sęk w tym, że mimo sortowania od największej liczby respektu (ORDER BY zgs.respect DESC), bierze ten gang, który ma najmniej respektu.

Oczekiwany wynik:
Kod:

id miny minx maxy maxx IFNULL(g.color,'909090')
34 1785.03 -2259.5 1981.03 -2063.5 FFFFFF


Ostatnio zmieniony przez KacperCL 2017-12-21, 18:31, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 

Combacior 





Informacje
Wiek: 22
Na forum: 3036 dni
Posty: 1512
Piwa: 2080
Respekt: 1040
Respekt: 1040

Wysłany: 2017-12-20, 22:52   



Użyłem dokładnie takie samo zapytanie jak podałeś, zwróciło mi dobry wynik (gang 1). Żeby się upewnić, że wybiera gang 1, dodałem dodatkowo do zapytania ID gangu

Kod:

SELECT * FROM (select z.id,z.miny,z.minx,z.maxy,z.maxx,IFNULL(g.color,'909090'),zgs.id_gang from zones z LEFT JOIN zones_gangscore zgs ON zgs.id_zone=z.id LEFT JOIN gangs g ON g.id=zgs.id_gang WHERE z.active=1 ORDER BY zgs.respect DESC) s1 GROUP BY id LIMIT 60;


Wynik

Kod:

34 1785.03 -2259.5 1981.03 2063.5 FFFFFF 1


Ostatnio zmieniony przez Combacior 2017-12-22, 12:09, w całości zmieniany 2 razy  
Postaw piwo autorowi tego posta
 

KacperCL 





Informacje
Nick w MP: [FS]Kacper[C]
Wiek: 19
Na forum: 2649 dni
Posty: 16
Respekt: 60

Wysłany: 2017-12-21, 17:56   



Ciekawe, testowałem na kilku bazach danych (ServerProject, serwer na XAMPP, nginx)

Zapytanie:
Kod:

-- phpMyAdmin SQL Dump
-- version 4.5.1
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Czas generowania: 21 Gru 2017, 17:24
-- Wersja serwera: 10.1.19-MariaDB
-- Wersja PHP: 5.6.28

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

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

--
-- Struktura tabeli dla tabeli `gangs`
--

CREATE TABLE `gangs` (
`id` smallint(1) UNSIGNED NOT NULL,
`color` char(6) CHARACTER SET utf8 NOT NULL DEFAULT '000000'
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;

--
-- Zrzut danych tabeli `gangs`
--

INSERT INTO `gangs` (`id`, `color`) VALUES
(1, '111111'),
(2, '222222');

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

--
-- Struktura tabeli dla tabeli `zones`
--

CREATE TABLE `zones` (
`id` int(10) UNSIGNED NOT NULL,
`miny` double NOT NULL,
`minx` double NOT NULL,
`maxy` double NOT NULL,
`maxx` double NOT NULL,
`active` tinyint(3) UNSIGNED NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;

--
-- Zrzut danych tabeli `zones`
--

INSERT INTO `zones` (`id`, `miny`, `minx`, `maxy`, `maxx`, `active`) VALUES
(1, 111.111, 111.111, 111.111, 111.111, 1);

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

--
-- Struktura tabeli dla tabeli `zones_gangscore`
--

CREATE TABLE `zones_gangscore` (
`id_zone` int(10) UNSIGNED NOT NULL,
`id_gang` smallint(5) UNSIGNED NOT NULL,
`respect` int(10) UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;

--
-- Zrzut danych tabeli `zones_gangscore`
--

INSERT INTO `zones_gangscore` (`id_zone`, `id_gang`, `respect`) VALUES
(1, 2, 100),
(1, 1, 5);

--
-- Indeksy dla zrzutów tabel
--

--
-- Indexes for table `gangs`
--
ALTER TABLE `gangs`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `zones`
--
ALTER TABLE `zones`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `zones_gangscore`
--
ALTER TABLE `zones_gangscore`
ADD PRIMARY KEY (`id_zone`,`id_gang`),
ADD KEY `respect` (`respect`);


Dalej pokazuje, że gang 1 jest najsilniejszym gangiem na dzielnicy 1 (mimo, iż gang 2 ma 100 respektu, a gang 1 ma tylko 5).

Postaw piwo autorowi tego posta
 

Combacior 





Informacje
Wiek: 22
Na forum: 3036 dni
Posty: 1512
Piwa: 2080
Respekt: 1040
Respekt: 1040

Wysłany: 2017-12-22, 12:10   



Faktycznie, u mnie na localhoscie zapytanie zwraca dobry wynik (WAMP, MySQL 5.6.17) a sprawdziłem na bazie danych od liveserver, to zwraca inaczej. To powinno działać

Kod:

SELECT id, minx, miny, maxx, maxy, IFNULL((SELECT id_gang FROM zones_gangscore zgs WHERE z.id = zgs.id_zone ORDER BY respect DESC LIMIT 1), -1) FROM zones z


_________________
Dołączę do ekipy serwera SA:MP DM/FR
Postaw piwo autorowi tego posta
 

KacperCL 





Informacje
Nick w MP: [FS]Kacper[C]
Wiek: 19
Na forum: 2649 dni
Posty: 16
Respekt: 60

Wysłany: 2017-12-22, 13:39   



A jakby jeszcze dołączyć kolor gangu, który ma największą ilość respektu na dzielnicy?
Kod:

IFNULL(g.color,'909090') FROM gangs g


Postaw piwo autorowi tego posta
 

Combacior 





Informacje
Wiek: 22
Na forum: 3036 dni
Posty: 1512
Piwa: 2080
Respekt: 1040
Respekt: 1040

Wysłany: 2017-12-23, 16:59   



Nie jestem tutaj od dawania gotowych rozwiązań, tylko od pomocy. Spróbuj najpierw samemu, jak się nie uda, to pomogę.

_________________
Dołączę do ekipy serwera SA:MP DM/FR
Postaw piwo autorowi tego posta
 

KacperCL 





Informacje
Nick w MP: [FS]Kacper[C]
Wiek: 19
Na forum: 2649 dni
Posty: 16
Respekt: 60

Wysłany: 2017-12-23, 21:29   



Aj, bym zapomniał. Pośpieszyłem się.
Zmieniłem nazwę kolumny id w tabeli zones na zid, bo się później to gryzło z tabelą gangs (tam też mamy id).

Kod:

SELECT zid, minx, miny, maxx, maxy,
(SELECT id_gang FROM zones_gangscore zgs WHERE z.zid = zgs.id_zone ORDER BY zgs.respect DESC LIMIT 1),
(SELECT IFNULL(color,'909090') FROM gangs g JOIN zones_gangscore zgs ON g.id=zgs.id_gang LIMIT 1)
FROM zones z,zones_gangscore zgs WHERE z.active=1 GROUP BY zid ORDER BY zid LIMIT 56


Pokazuje tylko 1 kolor - FFFFFF, id gangu poprawne

Postaw piwo autorowi tego posta
 

Combacior 





Informacje
Wiek: 22
Na forum: 3036 dni
Posty: 1512
Piwa: 2080
Respekt: 1040
Respekt: 1040

Wysłany: 2017-12-24, 10:45   



Jeśli są dwie kolumny o takich samych nazwach w różnych tabelach, to wystarczy dać nazwę tabeli albo alias przed nazwą kolumny (nazwa_tabeli.nazwa_kolumny), znasz to użycie, bo go używasz w niektórych zapytaniach. Ogólnie z tego co widzę, to strasznie kombinujesz - ograniczasz się do używania LEFT JOIN ... ON. Mogę zrozumieć, że tylko to znasz, ale wystarczy poszukać w google. Oprócz LEFT JOIN jest także RIGHT JOIN, OUTER JOIN, STRAIGHT_JOIN a także INNER_JOIN, którego ja użyłem, aby dołączyć kolor gangu. Tak samo nie wszystkie zapytania JOIN muszą zawierać klauzulę ON, bo jest także klauzula HAVING.

Kod:

SELECT z.id, minx, miny, maxx, maxy, (SELECT id_gang FROM zones_gangscore zgs WHERE z.id = zgs.id_zone ORDER BY respect DESC LIMIT 1) id_gang, g.color, g.id FROM zones z INNER JOIN gangs g HAVING id_gang = g.id


Zapytanie to już miałem gotowe jak pisałem poprzedni post, ale chciałem zobaczyć czy chociaż sam próbowałeś to zrobić czy czekać na gotowe.

_________________
Dołączę do ekipy serwera SA:MP DM/FR
Postaw piwo autorowi tego posta
 
Tagi: [mysql] :: pobieranie :: dzielnic :: gangowych :: respektu
Anonymous



Dołaczył: Wczoraj 0:00
Posty: 1
Skad: google.com


Anonymous Koniecznie zajrzyj na:








Wyświetl posty z ostatnich:   
Ten temat jest zablokowany bez możliwości zmiany postów lub pisania odpowiedzi
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Wersja do druku

Skocz do:  


phpBB by Przemo modified by xXx 2003-2016

Template GTAONLINE created by gtaonline.pl



Strona wygenerowana w 0,18 sekundy. Zapytań do SQL: 19