Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [mysq] Warunek operacje na zbiorach liczb
eai
post
Post #1





Grupa: Zarejestrowani
Postów: 367
Pomógł: 10
Dołączył: 20.05.2005

Ostrzeżenie: (0%)
-----


Witam

Mamy 3 tabele:

1. Tabela1
Kod
id|nazwa


2. Tabela2
Kod
id|nazwa


3. Tabela3
Kod
id|id_tabela1|id_tabela2


A teraz jak to ma działać:

Mamy takie dane:

Tabela1:
Kod
1|Tomek
2|Krzysiek
3|Wojtek
4|Agnieszka
5|Marek


Tabela2:
Kod
1|Miły
2|Agresywny
3|Życzliwy
4|Sumienny


Tabela3:
Kod
1|1|1
2|1|4
3|2|1
4|2|2
5|2|4
6|3|3
7|4|1
8|4|2
9|4|4
10|5|4

Pierwsza tabela zawiera osoby, druga zawiera cechy osobowości, a trzecia tabela przypisuje osobie konkretne osobowości.
Potrzebuję teraz takiego zapytania które pobierze mi z tabeli1 te osoby które mają określone cechy.
np. chcę pobrać te osoby które posiadają obie cechy np Miły oraz Sumienny.

Jak to zrobic?

Ten post edytował eai 19.02.2008, 15:04:17
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 6)
Cezar708
post
Post #2





Grupa: Zarejestrowani
Postów: 1 116
Pomógł: 119
Dołączył: 10.05.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


  1. SELECT * FROM Tabela1 t1, Tabela2 t2, Tabela3 t3 WHERE t3.id_tabela1 = t1.id AND t3.id_tabela2=t2.id AND t2.id IN (1,4)
Go to the top of the page
+Quote Post
krzyszbi
post
Post #3





Grupa: Zarejestrowani
Postów: 251
Pomógł: 13
Dołączył: 15.09.2005

Ostrzeżenie: (0%)
-----


  1. SELECT t1.nazwa FROM tabela1 t1 JOIN tab3 ON t1.id=t3.id_tabela2 AND t3.id_tabela2=x

gdzie x to id cechy jakiej szukasz
pisane z palca powinno działać ewentualnie nazwy tabel dostosuj
Go to the top of the page
+Quote Post
eai
post
Post #4





Grupa: Zarejestrowani
Postów: 367
Pomógł: 10
Dołączył: 20.05.2005

Ostrzeżenie: (0%)
-----


Tak już próbowałem, nie czytacie o co mi chodzi. Ja chce zwrócić te osoby które mają obie cechy 1,4 a wasze zapytania mi zwrócą tylko te osoby które posiadają cechy 1 lub 4 oraz 1 i 4, tu nie o to chodziło.

Wyjściem by było zrobić dwa joiny do tej samej tabeli z nowym aliasem i dać warunek, ale co jeśli naraz będę chciał pobrać te osoby które mają 20 określonych cech. Dawać 20 joinów? chyba da się to jakoś inaczej zrobić?

Ten post edytował eai 19.02.2008, 16:00:10
Go to the top of the page
+Quote Post
kitol
post
Post #5





Grupa: Zarejestrowani
Postów: 162
Pomógł: 26
Dołączył: 19.01.2007

Ostrzeżenie: (0%)
-----


Pisane z palca:

  1. SELECT osoba FROM tabela1 WHERE id_osoba IN(
  2. SELECT id_osoba FROM tabela3 WHERE id_cecha IN (1,4) GROUP BY id_osoba HAVING count(*)=2)
Go to the top of the page
+Quote Post
eai
post
Post #6





Grupa: Zarejestrowani
Postów: 367
Pomógł: 10
Dołączył: 20.05.2005

Ostrzeżenie: (0%)
-----


Może inaczej zrobie to na zasadzie porównywania ciągów tekstowych.

To zapytani mi ładnie wypisuje kto ma jakie cechy:
  1. SELECT tabela1.nazwa AS imie, GROUP_CONCAT(DISTINCT t2.nazwa ORDER BY t2.nazwa SEPARATOR ',') AS 'cechy'
  2. FROM tabela1 AS t1
  3. JOIN tabela3 AS t3 ON (t1.id= t3.id_tabela1)
  4. JOIN tabela2 AS t2 ON (t3.id_tabela2 = t2.id)
  5. GROUP BY t1.nazwa



Teraz tylko dorobić warunek where
  1. SELECT tabela1.nazwa AS imie, GROUP_CONCAT(DISTINCT t2.nazwa ORDER BY t2.nazwa SEPARATOR ', ') AS 'cechy'
  2. FROM tabela1 AS t1
  3. JOIN tabela3 AS t3 ON (t1.id= t3.id_tabela1)
  4. JOIN tabela2 AS t2 ON (t3.id_tabela2 = t2.id)
  5. WHERE '1,4' LIKE GROUP_CONCAT(DISTINCT t2.nazwa ORDER BY t2.nazwa SEPARATOR ',')
  6. GROUP BY t1.nazwa



Mam tylko problem ze składnią sql nie wiem jak w efekcie otrzymać LIKE %GROUP_CONCAT(DISTINCT t2.nazwa ORDER BY t2.nazwa SEPARATOR ', ')%

jak te %% do tego wstawić żeby wyłapał to?
Go to the top of the page
+Quote Post
Kicok
post
Post #7





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

Ostrzeżenie: (0%)
-----


  1. DROP TABLE IF EXISTS `cechy`;
  2. CREATE TABLE `cechy` (
  3. `id_cechy` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  4. `nazwa` varchar(50) NOT NULL,
  5. PRIMARY KEY USING BTREE (`id_cechy`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  7.  
  8. INSERT INTO `cechy` VALUES (1,'Miły'),(2,'Agresywny'),(3,'Życzliwy'),(4,'Sumienny');
  9.  
  10.  
  11.  
  12. DROP TABLE IF EXISTS `osoby`;
  13. CREATE TABLE `osoby` (
  14. `id_osoby` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  15. `nazwa` varchar(50) NOT NULL,
  16. PRIMARY KEY USING BTREE (`id_osoby`)
  17. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  18.  
  19. INSERT INTO `osoby` VALUES (1,'Tomek'),(2,'Krzysiek'),(3,'Wojtek'),(4,'Agnieszka'),(5,'Marek');
  20.  
  21.  
  22.  
  23. DROP TABLE IF EXISTS `osoby2cechy`;
  24. CREATE TABLE `osoby2cechy` (
  25. `id_osoby` int(10) UNSIGNED NOT NULL,
  26. `id_cechy` int(10) UNSIGNED NOT NULL,
  27. KEY `Index_id_osoby` (`id_osoby`),
  28. KEY `Index_id_cechy` (`id_cechy`)
  29. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  30.  
  31. INSERT INTO `osoby2cechy` VALUES (1,1),(1,4),(2,1),(2,2),(2,4),(3,3),(4,1),(4,2),(4,4),(5,4);



I zapytanie:
  1. SELECT o.*
  2. FROM osoby AS o
  3. JOIN osoby2cechy AS oc ON ( o.id_osoby = oc.id_osoby )
  4. WHERE oc.id_cechy IN ( 1, 4 )
  5. GROUP BY o.id_osoby
  6. HAVING COUNT( * ) = 2

IN ( 1, 4 ) - identyfikatory cech
COUNT( * ) = 2 - ilość cech

Czyli mniej więcej to co podał kitol. Na pewno 100x lepsze niż zamienianie identyfikatorów na tekst i zabawa w wyrażenia regularne.

Ten post edytował Kicok 19.02.2008, 18:36:26
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 17:18