Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Pobieranie danych - Zapytanie "wirtualne" pola
Forum PHP.pl > Forum > Bazy danych > MySQL
starcode
Witam!

Mam pytanie, czy w mySQL istnieje możliwość wykonania zapytania w poniżej przedstawionym układzie tabel.

Mamy tabelę główną, np.:

  1. CREATE TABLE main(
  2. id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  3. name varchar(96)
  4. );


oraz tabelę poboczną 'z wartościami', przypisanymi do konkretnych rekordów z tabeli 'main':

  1. CREATE TABLE vars(
  2. id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  3. main_id int NOT NULL,
  4. varName varchar(96),
  5. varValue varchar(96)
  6. );


W tabeli `main` przechowuję sobie jakieś rekordy o unikalnym ID, natomiast w tabeli `vars` przechowuję rekordy posiadające unikalne ID oraz ID rekordu z tabeli `main`, w tej tabeli znajduje się ponad to nazwa zmiennej oraz jej wartość.

Przykładowo:
  1. INSERT INTO `main` VALUES(NULL, 'rekord główny 1');
  2. INSERT INTO `main` VALUES(NULL, 'rekord główny 2');
  3.  
  4. INSERT INTO `vars` VALUES(NULL, '1', 'zmienna1', '2000');
  5. INSERT INTO `vars` VALUES(NULL, '1', 'zmienna2', 'abc');
  6. INSERT INTO `vars` VALUES(NULL, '1', 'zmienna3', 'def');
  7. INSERT INTO `vars` VALUES(NULL, '1', 'zmienna4', 'jakas inna wartość');
  8.  
  9. INSERT INTO `vars` VALUES(NULL, '2', 'zmienna1', '2000');
  10. INSERT INTO `vars` VALUES(NULL, '2', 'zmienna5', 'kolejna wartosc');
  11. INSERT INTO `vars` VALUES(NULL, '2', 'zmienna6', 'wartosc zmiennej 6');
  12. INSERT INTO `vars` VALUES(NULL, '2', 'zmienna9', 'unikalna przykładowa wartosc');


Moje pytanie jest następujące, czy wogóle możliwe jest pobranie rekordów z tabeli 'main' posiadających "przypisane" w tabeli 'vars' wartosci dla pola `varValue`= "2000" oraz jednoczesnie dla pola `varName` wartosc `zmienna1`?

Wiem, że można te dwie tabele połączyć np. Left join'em, ale nazwy kolumn będą się powtarzać. Po głowie mi chodzi, aby możliwe było dynamiczne nazwanie kolumn `varName` wartosią pola `varValue` i już łatwo wyszukiwać np. WHERE vars.main_id=main.id AND zmienna1='2000'.

Da radę to zrobić w ten sposób?
Może macie inny pomysł. Byłbym wdzięczny za jakąś wskazówkę / pomoc.
Chodzi mi tutuaj o ładne i w miarę optymalne zapytanie mySQL.

Pozdrawiam.

Ktoś ma jakiś pomysł jak to zrobić? Czy może jest to nie wykonalne?
abusiek
Nie wiem czy ja czegos nie rozumiem, czy wystarczy zapytac tak:

  1. SELECT * FROM main m, vars v WHERE v.varName = 'zmienna1' AND v.varValue = '2000' AND m.id = v.main_id;
starcode
Sorki. Być może nie wyraziłem się precyzyjnie.
W przypadku uwzględniania jednej zmiennej - TAK.

Mi chodziło o to by możliwe było pobranie np. rekordów 'zmienna1' = '2000' i (AND) 'zmienna2'='abc', czyli:

  1. SELECT * FROM main m, vars v WHERE v.varName = 'zmienna1' AND v.varValue = '2000' AND v.varName = 'zmienna2' AND v.varValue = 'abc' AND m.id = v.main_id;


Ale nie działa to niestety sad.gif
kitol
A może tak:
  1. SELECT * FROM main m, vars v WHERE ((v.varName = 'zmienna1' AND v.varValue = '2000' ) OR (v.varName = 'zmienna2' AND v.varValue = 'abc')) AND m.id = v.main_id;


warunek:
  1. v.varName = 'zmienna1' AND v.varName = 'zmienna2'

nigdy nie będzie spełniony dlatego twoje zapytanie nie działa.
starcode
Niestety nie.

Zapytanie to zwraca:

  1. id name id main_id varName varValue
  2. 1 rekord główny 1 1 zmienna1 2000
  3. 1 rekord główny 2 1 zmienna2 abc
  4. 2 rekord główny 5 2 zmienna1 2000


Oczywiście można wykonać GRUP BY `main_id` aby zapobiec powtarzaniu się rekordów, jednak nie zmieni to faktu, że `rekord główny` z ID = 2, nie powinien zostać zwrócony, ponieważ nie posiada zmienna2 o wartości abc (takowy posiada jedynie `rekord główny` z ID = 1).

Zapytanie to powinno mieć wszędzie AND'y, czyli np.:

  1. SELECT * FROM main m, vars v
  2. WHERE ((v.varName = 'zmienna1' AND v.varValue = '2000' ) [b]AND[/b] (v.varName = 'zmienna2' AND v.varValue = 'abc')) AND m.id = v.main_id;


Ale niestety powyższe nie zwraca żadnego wyniku.

Ma ktoś jakiś pomysł? Czy faktycznie jest to nierozwiązywalny problem i nikt nie jest w stanie napisać odpowiedniego zapytania SQL?
dr_bonzo
  1. EXPLAIN SELECT * FROM vars WHERE ( varName = 'zmienna2' AND varValue = 'abc' AND main_id IN (SELECT main_id FROM vars WHERE ( varName = 'zmienna1' AND varValue = '2000' ) ) )


i zaloz index na main_id

Tyle ze dla wielu warunkow to bedzie... kiepskie


  1. SELECT * FROM main m, vars v
  2. WHERE ((v.varName = 'zmienna1' AND v.varValue = '2000' ) AND (v.varName = 'zmienna2' AND v.varValue = 'abc')) AND m.id = v.main_id;

Nie zwroci ci nic, bo chcesz rekordow w ktorych varName jest jednoczesnie == 'zmienna1' i 'zmienna2', a to jest oczywiscie nie mozliwe smile.gif
starcode
No właśnie wiem. Dlatego w piewszym poście zapytałem czy da radę jakimś sposobem (mi nie znanym) nazwanie kolumn dynamicznie, czyli kolumny varName przyjmują za nazwę swoją zawartość. Wówczas szło by z górki, szybko i optymalnie...

Ktoś o czymś takim słyszał / jest coś takiego możliwe?
dr_bonzo
Nie da sie tak "dynamicznie" nazwac kolumn, a nawet gdyby sie dalo to baza i tak by to musiala przetlumaczyc na tak zlozone (lub prostsze - o ile sie da) zapytanie.
Bo nie pytasz o 1 rekord z kilkoma warunkami where, ale o cos bardziej skomplikowanego
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.