Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Skompikowane zapytanie SQL do niestandardowego wyciągania rekodrów z bazy
Forum PHP.pl > Forum > Bazy danych > MySQL
robson_admin
Witam,

Mam pewien problem. Otóż chciałbym zrobić niestandardowe wyciąganie rekordów z bazy danych.

Przykadowa baza danych:
  1. DROP TABLE IF EXISTS `proces`;
  2. CREATE TABLE `proces` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `user` int(11) DEFAULT NULL,
  5. `status` int(1) NOT NULL DEFAULT '0',
  6. `proc` varchar(255) DEFAULT NULL,
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED;
  9.  
  10. INSERT INTO `proces` VALUES (1,1,0,'p1');
  11. INSERT INTO `proces` VALUES (2,1,0,'p2');
  12. INSERT INTO `proces` VALUES (3,1,0,'p3');
  13. INSERT INTO `proces` VALUES (4,2,0,'p4');
  14. INSERT INTO `proces` VALUES (5,2,0,'p5');
  15. INSERT INTO `proces` VALUES (6,3,0,'p6');

System pobiera pojedynczo rekordy(ASC id) a następnie je wykonuje zmieniając status na 1. Cały problem polega na tym że wykonanie jednego procesu trwa około minuty i gdy jeden user doda trochę więcej rekordów to reszta (która doda trochę później) czeka kilkanaście minut na rozpoczęcie wykonywania co ich trochę irytuje.

Chciałbym przerobić zapytanie aby rekordy były wybierane w inny spsób, a mianowicie po jednym rekordzie od każdego usera. Czyli w kolejności następującej(id): 1,4,6,2,5,3


Czy ktoś wie jak takie coś zrobić? Oczywiście w międzyczasie inny user może dodać kolejny proces i wtedy jego pierwszy wpis musi zostać wybrany w ciągu trwającego przejścia po wszystkich userach.

Z góry dzięki,
pozdrzwiam

Żaden "specjalista" nie umie pomóc?


W innych postach jakoś "specjaliści" się wypowiadają.



Ktoś posiada wiedzę wykraczającą ponad podstawowe zapytania?
Mchl
Może zamiast prowkować 'specjalistów' zastanów się czy wystarczająco dobrze opisałeś problem.
robson_admin
Podałem kod bazy i co chce mieć na wyjściu + opis. Wg mnie jest to wystarczające....
Mchl
Tak na początek, nie masz w ogóle czasu dodania procesu do kolejki, więc nie sposób stwierdzić, który proces pojawił się wcześniej. Sortowanie po kolumnie auto_increment nie jest tutaj pewnym rozwiązaniem.

Dalej:
Kod
SELECT user, MIN(id) AS id FROM proces WHERE status = 0 GROUP BY user


da ci najmniejsze id procesów niewykonanych dla każdego użytkownika (normalnie powinieneś to zrobić po kolumnie z czasem dodania procesu do kolejki)

dalej

Kod
SELECT p.id, p.user, p.status, p.proc FROM proces AS p CROSS JOIN (SELECT user, MIN(id) AS id FROM proces WHERE status = 0 GROUP BY user) AS sq USING (user,id)

i masz już listę procesów do wykonania w danym cyklu.
robson_admin
Hmm no nie do końca to działa tak jak chciałem...

"System pobiera pojedynczo rekordy(ASC id) a następnie je wykonuje zmieniając status na 1"

i wtedy to zapytanie się gubi. Bo myśli że dany user nie wykonuje żadnego procesu...



Co do daty dodania to mogę zrobić dodatkową tabele o formacie DateTime i nazwie data.
Mchl
Wiesz, trudno coś więcej wymyśleć nie znając szczegółów tego jak dział ten system.

Ja bym podszedł do tego tak:

Zrobiłbym dodatkową tabelę, do której przy pomocy zapytania powyżej przerzucałbym procesy do wykonania (wystarczy same id).
Jak długo w tej tabeli są niewykonane procesy, tak długo system zajmuje się ich wykonywaniem. Gdy wszystkie wykona, sięga do tabeli proces po nową porcję.

Podobną metodę można zastosować dodając do tabeli proces nową kolumnę, w której zapisywałbyś na przykład czas rozpoczęcia wykonywania danej porcji procesów.
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.