Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MYSQL] Jedno pole kilka wartości
Forum PHP.pl > Forum > Przedszkole
wlamywacz
Cześć!

Aktualnie pracuję nad systemem w którym kilka osób może sobie `przygarnąć` jeden rekord z mysql. Myślałem aby to zrobić tak że w bazie będzie pole `users` i przykładowa w nim wartość to: `user1, user2, user3` gdyż nie wiem ile userów może sobie rekord `przygarnąć`. Dodanie tego to pryszcz jednak w jaki sposób usunąć np. wartość `user2 ,` bez usuwania reszty ?
AxZx
w rozwijaniu bazy idz w dol nie w bok.
stworz tabele laczaca danego usera z wierszem z innej tabeli.
jak bedziesz chcial usunac usuniesz tylko to przypisanie - wtedy bedziesz wiedzial ze user nie jest powiazany z tym wierszem.
acztery
  1. UPDATE table_name
  2. SET column_name = REPLACE(column_name , 'user2' , '');
  3. WHERE id = id_usera


może tak

pomyśl nad zmianą struktury bazy też miałem ten problem i się dałem przekonać.
wlamywacz
Będzie to niezbyt możliwe gdyż system który tworzę jest bardzo zaawansowany.
nospor
przy takim wykonaniu to daleko mu do zaawansowanosci winksmiley.jpg (chodzi mi o tabele)
zrob jak polecil AxZx - jedyne sensowne rozwiązanie
No chyba ze system jest az tak zaawansowany, ze tak prostych rozwiazan nie mozna zastosowac winksmiley.jpg
wlamywacz
Niestety ale nie mam czasu Ci tego tłumaczyć nospor. Nie wszyscy piszą fora i systemy newsów. Pozdro i dzięki
Balon
Cytat
Niestety ale nie mam czasu Ci tego tłumaczyć nospor bo nie mam czasu.

Yhm.. Nie masz czasu tłumaczyć, bo nie masz czasu? smile.gif

Bardzo zaawansowane systemy wymagają zaawansowanych rozwiązań. Twoje rozwiązanie jest złe, idziesz złą drogą. Rozwiązanie AxZx ułatwi Ci wiele spraw.
wlamywacz
Fakt pomyliłem się bo się śpieszyłem. Pole to służy tylko do wyświetlenia kto przygarnął dany rekord aby odciążyć system. Właściwa lista znajduję się w osobnej tabeli.

Btw. Dzisiaj 18 urodziny ^^
nospor
Cytat
Pole to służy tylko do wyświetlenia kto przygarnął dany rekord aby odciążyć system. Właściwa lista znajduję się w osobnej tabeli.
No i wlasnie "tylko do tego" najlepszym rozwiązaniem jest dodatkowa tabela wiążąca. Predzej czy później sie o tym przekonasz, szczegolnie ze piszesz "bardzo zaawansowany" system. Więc chyba lepiej by sie o tym dowiedzial wczesniej i skorzystal z rad bardziej doswiadczonych userow, poto chyba pytasz na forum?
wlamywacz
Tabela istnieje, jednak musiałbym wykonać dla każdego rekordu osobne zapytanie pobierające kto ma przygarnięty ten rekord a gdy tych rekordów będzie ze 100 to robię 100 dodatkowych zapytań.
nospor
Cytat
a gdy tych rekordów będzie ze 100 to robię 100 dodatkowych zapytań.
blinksmiley.gif
Jedno zapytanie. Rekordow moze byc nawet 1000 a i tak do pobrania kto ma cos przygarnietego wystarczy jedno zapytanie.
Jak masz problem to sie dopytaj a nie wymyslac jakies cudne teorie winksmiley.jpg Naprawde myslales ze bysmy ci polecili tak nieoptymalne rozwiązanie? Troche wiary w nas.
phpion
Ja bym zrobił osobne pole np. "przygarniete", w którym przechowywałbym id przygarniętych rekordów rozdzielone jakimś separatorem np. |:
Kod
1|2|3|4|5

Głupie? No pewnie, że głupie.

Może zanim zaczniesz pisać zaawansowane aplikacje sięgnij do podstaw projektowania baz danych... To taka moja sugestia. Jedyne poprawne rozwiązanie w tej sytuacji to osobna tabela z dwoma kolumnami łącząca rekord-matkę z rekordem-przygarniętym (tak jak napisał ~AxZx).

Swoją drogą: zaawansowany system i 100 rekordów? Piszesz jakąś wypasioną księgę gości?
wlamywacz
  1. SELECT `users`.`group`, `users`.`user`, `work`.* FROM `users` LEFT JOIN `work` ON `users`.`group` = `work`.`group` WHERE `users`.`user` = '$user' AND `users`.`group` = `work`.`group` AND `work`.`end` = 0 AND `work`.`users` = '' ORDER BY `work`.`date_add` DESC

To powiedz mi jak do tego zapytania dorzucić pobranie userów z tableli `uwork` gdzie `uwork`.`id_work` = `work`. `id`.
nospor
Napisze konkretnie co chcesz zrobic, bo sie chyba zgubilem. Przeciez userow juz pobierasz.
wlamywacz
No właśnie to jest zaawansowany system aaevil.gif Pobiera dane z tabeli users gdzie mam grupe do której należy, następnie łącze work odpowiednim warunkiem tak aby wybrać tylko zlecenia które należą do jego grupy. I wyświetlam je ale dodatkowo chce aby było w tym info kto już pracuję nad tym zleceniem. A id osób które mają jakie prace znajduję się w tabeli `uwork`.
nospor
Cytat
No właśnie to jest zaawansowany system
to ty zaawansowanych systemow nie widziales.
ja sie zgubilem nie dlatego ze to takie "zaawansowane" ale dlatego ze nie wiedzialem oco ci chodzi. lekka roznica wiec sie tak nie podniecaj

  1. SELECT `users`.`group`, `users`.`user`, `work`.*, u2.NAME, u2.SURNAME_CZY_CO_TAM_MASZ FROM `users` LEFT JOIN `work` ON `users`.`group` = `work`.`group`
  2. LEFT JOIN uwork ON uwork.id_work = work.id
  3. LEFT JOIN users u2 ON uwork.id_user = u2.id
  4. WHERE `users`.`user` = '$user' AND `users`.`group` = `work`.`group` AND `work`.`end` = 0 AND `work`.`users` = '' ORDER BY `work`.`date_add` DESC

oczywiscie w php bedziesz musial to odpowiednio pobrac, bo ci pare rekordow zwroci.
Od biedy mozna by sie zabawic w group by i concat

edit: tak sobie przez noc pomyslalem jeszcze, ze mozesz sobie troche ulatwic sprawe i rozbic to zapytanie na dwa (zauwaz ze mowie dwa a nie sto winksmiley.jpg )
Pierwsze zapytanie takie co miales do tej pory.
Drugie zapytanie, ktore dla znalezionych rekordow z pierwszego zapytania, szuka rekordow z powiązanych tak jak chcesz. W efekcie otrzymasz to samo jakbys dal to wszystko w jednym, ale przy tej drugiej opcji latwiej ci bedzie moze to ogarnac
phpion
@nospor ma rację. Ja osobiście często korzystam z takiego rozwiązania.
Przykładowo mamy produkty i każdy produkt może należeć do wielu kategorii. Trzeba teraz wyświetlić listę produktów wraz z kategoriami (w postaci linków), do których one należą. Można zrobić SELECT'a pobierającego potrzebne produkty, a potem przy wyświetlaniu w pętli pobierać jeszcze kategorie. Mamy wtedy n+1 zapytań, gdzie n to liczba znalezionych produktów.
Można jednak do tego podejść inaczej. Najpierw pobierasz produkty, które cię interesują. Następnie (w pętli) zapisujesz ich id do tablicy. Drugim zapytaniem pobierasz kategorie tych produktów, które zawierają się w tej tablicy (WHERE product_id IN ('.implode(', ', $array).')). Sprytne zapisanie tych danych do tablicy (indeks tablicy = id produktu) i już jesteś prezes. Wystarczy pokombinować. Z n+1 zapytań robią się 2.
wlamywacz
Mieliście rację że to cholerstwo się na mnie zemści sadsmiley02.gif Przepraszam za swoje pyszałkowate zachowanie sciana.gif Może spokojnie wyjaśnię i ktoś pomoże. Mam tabele `jobs` w której znajdują się zlecenie o unikalnym id, tabele `ujobs` w której znajduję się user z przypisanym id zlecenia które wykonuję no i tabele `users` w której jest info odnośnie userów. Jak zrobić aby wybrać wszystkie zlecenia których warunek `work`.`public` = 1 wraz z wszystkimi osoba które mają to zlecenie?

No i muszę przepisać te kilkanaście zapytań do bazy bo nie mam jak wyzwalaczy odpalić : (

Pozdrawiam
nospor
No a co ci nie pasuje w moim poprzednim poscie? smile.gif
wlamywacz
Niestety zapytanie:
  1. SELECT `users`.`group`, `users`.`user`, `jobs`.*, u2.* FROM `users` LEFT JOIN `jobs` ON `users`.`group` = `jobs`.`group`
  2. LEFT JOIN ujobs ON ujobs.id_work = jobs.id
  3. LEFT JOIN users u2 ON ujobs.user = u2.id
  4. WHERE `users`.`user` = 'Daniel Burchardt' AND `users`.`group` = `jobs`.`group` AND `jobs`.`end` = 0 AND `jobs`.`users` = 'Daniel Burchardt' ORDER BY `jobs`.`date_add` DESC


Zwraca jeden rekord podczas gdy powinny być dwa sad.gif Poniżej zrzut tabel:
  1. CREATE TABLE `jobs` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `date_add` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  4. `group` mediumint(9) DEFAULT NULL,
  5. `public` smallint(6) DEFAULT NULL,
  6. `title` longtext,
  7. `users` longtext,
  8. `end` smallint(6) DEFAULT NULL,
  9. UNIQUE KEY `id` (`id`)
  10. )
  11.  
  12. CREATE TABLE `ujobs` (
  13. `user` varchar(255) NOT NULL DEFAULT '',
  14. `id_work` int(11) DEFAULT NULL,
  15. UNIQUE KEY `user` (`user`,`id_work`)
  16. )
  17.  
  18. CREATE TABLE `users` (
  19. `id` int(11) NOT NULL AUTO_INCREMENT,
  20. `user` varchar(255) DEFAULT NULL,
  21. `pass` varchar(32) DEFAULT NULL,
  22. `group` smallint(6) DEFAULT NULL,
  23. `cash` smallint(6) DEFAULT NULL,
  24. `open_time` varchar(32) DEFAULT NULL,
  25. `pph` int(11) DEFAULT NULL,
  26. `phone` float DEFAULT NULL,
  27. `type` smallint(6) DEFAULT NULL,
  28. UNIQUE KEY `id` (`id`,`user`)
  29. )
nospor
Cytat
CREATE TABLE `ujobs` (
`user` varchar(255) NOT NULL default '',
`id_work` int(11) default NULL,
UNIQUE KEY `user` (`user`,`id_work`)
)

Czemu laczysz usera poprzez nazwe? user tak samo jak i work ma byc łączone przez ID

Czemu w tabeli jobs masz nadal users? Łączysz nasz sposob ze swoim? Przeciez to nie wypali.

Zapytania nie mam sily analizowac. Za bardzo nie zakumales oco chodzi.
Czemu w zapytaniu dajesz dwa razy Daniel Burchardt i czemu raz jest w users?

Popraw to wszystko, uzyj metody drugiej, czyli pobierz sobie id userow, a nastepnie drugim zapytaniem pobierz info dla nich, bo z jednym zapytaniem jak pisalem wczesniej sobie nie poradzisz.
wlamywacz
  1. SELECT GROUP_CONCAT(`users`.`user`) AS `users`, `jobs`.*, `ujobs`.*, `users`.* FROM `jobs` LEFT JOIN `ujobs` ON `jobs`.`id` = `ujobs`.`id_work` LEFT JOIN `users` ON `users`.`id` = `ujobs`.`user` WHERE `jobs`.`public` = 1 GROUP BY `jobs`.`id`

To działa! Pamiętajcie GROUP_CONCAT na polu INT da jakąś dziwną wartość i wydaję się że nie działa winksmiley.jpg)

Pozdrawiam
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.