|
SQL baze podataka - Sponzor: Baze-Podataka.net MySQL, MSSQL, Oracle, Access, ODBC. Ako imate problem brže i preciznije ćete dobiti odgovor ako priložite strukturu tabela ili skript koji kreira tabele i puni ih test podacima umesto što to problem opisujete samo rečima. Sponzor: Baze-Podataka.net - Blog o bazama podataka |
|
Alati teme | Način prikaza |
27. 05. 2013. | #1 |
emperor Selassie
Grand Master
|
[MySQL] nešto kao where IN, ali da hvata sve
Možda je malo konfuzan naslov teme ali evo šta pokušavam: Imam sajt sa nekretninama i svaka od nekretnina može da ima neke "pogodnosti" pridružne (amenities, ne znam da li sam lepo preveo). To je sve organizovano ovako u tabelama (koje su bitne za problem):
1. properies - id, title, description, price, ... 2. amenities - id, name 3. amenities_properties - amenity_id, property_id E sad, pri pretrazi nekretnina imam checkboxove kojima treba da se suze rezultati pretrage na samo one nekretnine koje imaju sve označene "pogodnosti" pridružene. Probao sam ovako: Kôd:
SELECT DISTINCT `properties`.* FROM `properties` ... LEFT JOIN `amenities_properties` ON `properties`.`id` = `amenities_properties`.`property_id` ... WHERE `amenities_properties`.`amenity_id` IN (9, 15, 24) Kôd:
SELECT DISTINCT `properties`.* FROM `properties` ... LEFT JOIN `amenities_properties` ON `properties`.`id` = `amenities_properties`.`property_id` ... WHERE ( `amenities_properties`.`amenity_id` = 9 AND `amenities_properties`.`amenity_id` = 15 AND `amenities_properties`.`amenity_id` = 24 ) Da li ima neki način da ja dohvatim sve nekretnine koje imaju sve pogodnosti pridružene, a da ne moram da dohvatim sve koje imaju bar jednu (sa where... in ()) pa da onda iz PHP-a proveravam svaku ponaosob? |
27. 05. 2013. | #2 |
expert
Expert
Datum učlanjenja: 27.11.2005
Poruke: 543
Hvala: 47
57 "Hvala" u 31 poruka
|
Ovaj drugi upit da napišeš kao višestruki JOIN nad tabelom `amenities_properties` gde će po jedan JOIN da ti bude za svaki atribut koji želiš da koristiš u Where... pseudo ovako:
Kôd:
... LEFT JOIN `amenities_properties` ap1 ON `properties`.`id` = ap1.`property_id` LEFT JOIN `amenities_properties` ap2 ON `properties`.`id` = ap2.`property_id` LEFT JOIN `amenities_properties` ap3 ON `properties`.`id` = ap3.`property_id` WHERE ap1.`amenity_id` = 9 AND ap2.`amenity_id` = 15 AND ap2.`amenity_id` = 24 |
27. 05. 2013. | #3 |
emperor Selassie
Grand Master
|
Uh, baš je PITA fora je što koristim ORM pa ne znam da li uopšte mogu da odradim višestruki JOIN ovako, ali čak i da mogu, šta ako neko označi 50 tih pogodnosti, je l' normalno da MySQL onda radi 50 puta join iste tabele? Nema neki jednostavniji način?
|
27. 05. 2013. | #4 |
emperor Selassie
Grand Master
|
Ne mogu da editujem prethodnu poruku pa se izvinjavam zbog duplog posta. Elem, naiđoh na ovo:
Kôd:
select properties.* from properties join amenities_properties on properties.id = amenities_properties.property_id where amenities_properties.amenity_id in (9,15,24) group by properties.id having count(*) = 3 |
27. 05. 2013. | #5 |
expert
Expert
Datum učlanjenja: 27.11.2005
Poruke: 543
Hvala: 47
57 "Hvala" u 31 poruka
|
Ako nećeš da budeš kandidat za Najgori SQL upit, bolje je da napraviš tabelu za pretraživanje:
Kôd:
property_id | attr_9 | attr_15 | attr_16 | attr_20 Pa u subSELECT upotrebi sve nađeno upitom nad ovom tabelom. Ako ima neko elegantnije rešenje, voleo bih i ja da ga znam. Osnovni problem je nepostojanje INTERSECT operatora u MySQL. |
27. 05. 2013. | #6 |
emperor Selassie
Grand Master
|
Pa dobro sad, moj upit za pretragu još nije dostigao ni deo dužine upita (nivoa haosa) sa linkovane teme
Onda bih za svaki checkbox morao da imam posebnu kolonu u tabeli? To mi se ne sviđa jer korisnik može da doda svoje checkboxove, tj. "pogodnosti" |
28. 05. 2013. | #7 |
Dejan Katašić
Wrote a book
Datum učlanjenja: 10.06.2005
Lokacija: Novi Sad
Poruke: 1.017
Hvala: 129
86 "Hvala" u 43 poruka
|
Kôd:
select * from properties p where 1 = 1 and exists(select * from amenities_properties ap where ap.property_id = p.id and ap.amenity_id = 9) and exists(select * from amenities_properties ap where ap.property_id = p.id and ap.amenity_id = 15) and exists(select * from amenities_properties ap where ap.property_id = p.id and ap.amenity_id = 24) |
"Hvala" noviKorisnik za poruku: |
28. 05. 2013. | #9 |
Ivan Dilber
Sir Write-a-Lot
|
seljacka (ali brza) fora je da dodas text polje i u njega upises listu amenities i onda koristis full text search (boolean mode) da nadjes to sto ti treba. Posto se pretpostavljam atributi relativno retko edituju onda malo extra posla oko toga nije problem, a search ce da ti bude mnogo brzi nego sa normalizovanom bazom
__________________
Leadership is the art of getting people to want to do what you know must be done. |
29. 05. 2013. | #10 |
emperor Selassie
Grand Master
|
Ovo jablanovo rešenje radi ko sat i to bez dodatnih podupita i joinova... a koliko je efikasno ostaje da vidimo kad bude mnogo nekretnina sa mnogo pogodnosti
Hvala svima! Poslednja izmena od Nemanja Avramović : 29. 05. 2013. u 12:50. |
|
|