Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL]Grupowanie wg. masek z innej tabeli
Forum PHP.pl > Forum > Bazy danych
timon27
Posiadam dwie tabele w mysql.
Tabela towarów:
  1. NAZWA CENA
  2. krem jkiśtam 2,4
  3. krem cośtam 1,5
  4. szampon cośtam 3,4
  5. szampon cośtam2 3,5

oraz początków nazw - identyfikująca rodzaj produktu:
  1. MASKA
  2. krem
  3. szampon

Chciałbym pogrupować pierszą tabelę wg początków nazw z drugiej.
(kolumna 'cena' jest tylko po to aby pokazać że grupowanie nie jest bezsensowne).
Jakieś pomysły?
Pierwszej tabeli nie mogę edytować.

Żeby nie było: mysql znam, nie radzę sobie tylko ze zmienną długością masek.
Gdyby wszystkie maski miały tą samą długość nie miałbym problemu:
  1. SELECT * FROM
  2. (SELECT *,SUBSTR(nazwa,1,5) AS maska FROM towary) AS first
  3. JOIN maski
  4. ON maski.maska=first.maska
  5. GROUP BY maski.maska
mortus
Bardzo dziwne podejście i w ogóle nieoptymalne. Taki rodzaj produktu powinien być chyba czymś w stylu kategorii. Niemniej da się to zrobić, choć nie wiem po co to złączenie.
  1. SELECT `temp`.`t_maska` `maska`, SUM(`temp`.`t_cena`) `cena_razem` FROM (
  2. SELECT SUBSTRING_INDEX(`t`.`nazwa`, ' ', 1) `t_maska`, `t`.`cena` `t_cena` FROM `towary` `t`
  3. ) `temp`
  4. LEFT JOIN `maski` `m` ON `temp`.`t_maska` = `m`.`maska`
  5. GROUP BY `m`.`maska`

Dać się da, ale nie polecam i radzę się dobrze zastanowić nad funkcjonalnością aplikacji i strukturą bazy danych.
timon27
Struktura baz danych pochodzi z programu kasowego.
Program nie jest mojego autorstwa, nie mam mozliwości ani prawa jego modyfikacji.

Zapytanie niestety działa tylko jeśli po masce jest spacja.
Niestety mam też inne sytuacje:
  1. NAZWA CENA
  2. krem jkiśtam 2,4
  3. krem cośtam 1,5
  4. cośtam 1,2
  5. cośinnego 3,4


  1. MASKA
  2. krem
  3. coś
mortus
Najgorszym z możliwych rozwiązań jest takie złączenie:
  1. SELECT `m`.`maska`, SUM(`t`.`cena`) FROM `towary` `t`, `maski` `m`
  2. WHERE LOCATE(`m`.`maska`, `t`.`nazwa`) = 1
  3. GROUP BY `m`.`maska`


Najbardziej optymalnym i w dodatku bezinwazyjnym (nie trzeba modyfikować czyjejś aplikacji) rozwiązaniem wydaje się być utworzenie trzeciej tabeli maski_towarow zawierającej jedynie dwie kolumny id_maski i id_towaru, obie będące kluczem głównym. Później jednorazowym zapytaniem
  1. INSERT INTO `maski_towarow` SELECT `m`.`id`, `t`.`id` FROM `maski` `m`, `towary` `t` WHERE LOCATE(`m`.`maska`, `t`.`nazwa`) = 1

uzupełniamy tabelę maski_towarow i w naszej "części" aplikacji korzystamy właśnie z niej:
  1. SELECT `m`.`maska`, SUM(`t`.`cena`) FROM `maski` `m`
  2. LEFT JOIN `maski_towarow` `mt` ON `m`.`id` = `mt`.`id_maski`
  3. LEFT JOIN `towary` `t` ON `mt`.`id_towaru` = `t`.`id`
  4. GROUP BY `m`.`id`
timon27
Cytat(mortus @ 7.05.2013, 12:28:08 ) *
utworzenie trzeciej tabeli maski_towarow zawierającej jedynie dwie kolumny id_maski i id_towaru

Jak niby mam to zrobić ?
Przed każdym wywołaniem zapytania (o które pytam w tym wątku) mam tworzyć tę tabelę?
To dopiero będzie nieoptymalne.
Bo nie wyobrażam sobie monitorować w czasie rzeczywistym
czy ktoś właśnie nie dodaje towarów do tabeli
aby uzupełnić tabelę powiązań.

Cytat(mortus @ 7.05.2013, 12:28:08 ) *
LOCATE(nazwa,maska)=1

Dokładnie o to mi chodziło.
Czas wykonania 3 sekundy
(kilkanaście tysięcy towarów, setka masek)
- akceptowalny przy własnych zestawieniach,
choć faktycznie nieakceptowalne gdybym potrzebował to ze strony klientów.
mortus
No ale jeśli ktoś dodaje towar to i musi podać powiązaną z nim maskę, a to wszystko możemy dzięki TRIGGER-om wpakować do naszej tabeli maski_produktow (tę tabelę tworzymy i uzupełniamy tylko raz istniejącymi danymi, a później już na bieżąco danymi wprowadzonymi przez użytkownika).

Nie ma potrzeby modyfikowania czegokolwiek w istniejącej już aplikacji.
timon27
Cytat(mortus @ 7.05.2013, 12:57:47 ) *
No ale jeśli ktoś dodaje towar to i musi podać powiązaną z nim maskę


Nie, nie nie musi. Skąd pomysł że musi?
Miałby wychodzić z programu, aby go gdzieś podać?
Jeśli dodaje się nowy RODZAJ towaru, to wtedy tak, ale to się dziej bardzo rzadko.

Cytat(mortus @ 7.05.2013, 12:57:47 ) *
a później już na bieżąco danymi wprowadzonymi przez użytkownika


No ale w jaki sposób? Mam przechwytywać dodawanie towarów do bazy? To będzie niemożliwe.
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.