Autor Zpráva
SwimX
Profil
Dobrý den,
mám tabulku
spolecnosti kde je název, okres, kraj, atd.
pak tabulku hodnoceni kde je id_spolecnosti, id_sportu, hodnoceni

a potřebuji dotaz který mi vybere společnost ze zadaného kraje, která nabízí zadané sporty.

Ukázkový příklad.
spolecnosti
id | nazev | okres |
1    Aaa         4
2    Bbb         6

hodnoceni
id | id_spolecnosti | id_sportu | hodnoceni
1       1              2                95
2       1              5                55
3       1              8                100


na základě filtrů (selectů a checkboxů) mám:
okres = 4
id_sportu = 2 and id_sportu = 8

dotaz:
SELECT spolecnosti.id, nazev_cs FROM spolecnosti inner join hodnoceni on spolecnosti.id = hodnoceni.id_spolecnost WHERE (id_sport = 8 and id_sport = 11) and id_okres = 7 and id_kraj = 3 and id_typ_hotel = 5


to funguje pokud je vybrán jen jeden sport (chápu proč, ale už nevím jak udělat aby to joinulo všechny záznamy a v nich hledalo id_sportu)
Tuším že jsem to někdy dělal, a že se použíalo GROUP ale teď jsem na to nepřišel



Děkuji za rady
Alphard
Profil
Nešlo by where id_sport in (8, 11)?
SwimX
Profil
Alphard:
zajímavé, neznám, zkusím :) díky
SwimX
Profil
Alphard:
pokud vyberu 2 sporty a oba splňují -> tak dostanu dva identické výsledky (vyřeším přes DISTINCT)
ale pokud vyberu jeden který vyhovuje a další co ne -> přesto dostanu výsledek. To je sice zajímavé, ale myslím, že nežádoucí. Eště prodiskutuju se zadavatelem. Ale předpokládám že to neni uplně ono.
Alphard
Profil
SwimX:
Aha, popisované chování je přesně takové, jaké jsem si myslel, že chcete :-) Takže se omlouvám za nepozornost, jdu si znovu přečíst zadání a jestli mě něco napadne, tak napíši.
SwimX
Profil
Alphard:
sám nevím co přesně chci :) být to na mě, tak to tak nechám, uvidíme co vymslí šéf, až se dostane k icq a odpoví.

ostatně where in () je stejne jako když jsem udělal: WHERE (id_sport = 8 or id_sport = 11) and :))
Alphard
Profil
SwimX:
ostatně where in () je stejne jako když jsem udělal: WHERE (id_sport = 8 or id_sport = 11) and :))
je, ale dá se lépe implementovat: where id in (implode...

Tento typ dotazů jsem neměl nikdy rád a dneska se mi už nechce moc myslet :-) Řeší se to seskupením a pak nějakým počítáním, myslím, že podstata bude v tomhle:
having (count(*)) >= 2
TomášK
Profil
Popravdě řečeno, začal jsem psát odpověď už před chvílí, ale pak jsem přestal - chtěl jsem počkat, jestli se chytne Kajman, protože mám pocit, že moje řešení není úplně nejlepší a jde to i lépe. Sám to řeším to přes
HAVING COUNT(DISTINCT id_sport) == 2;
stejně jako Alphard. Nalíbí se mi na tom, že je tam GROUP BY i když se mi zdá, že by to mělo jít i bez něj. Druhé řešení, které mě napadlo je přes sadu joinů:
SELECT ...
FROM 
    spolecnosti s1, spolecnosti s2
WHERE 
    s1.id = s2.id AND
    s1.id_sportu = 8 AND
    s2.id_sportu = 11

Pro malý počet sportů by to mohlo být i rychlejší (ale nemám to vyzkoušené), ale mít pak 10 tabulek v dotazu má k ideálu také daleko.
SwimX
Profil
Alphard:
je, ale dá se lépe implementovat: where id in (implode...
where id = (implode(' or id = ', $array);
TomášK:
j s tim group by sem to kdysi dělal, už jsem si vzpomněl i kde. Tady:

SELECT coalesce(pocet_diskuze, 0) as pocet_diskuze, menu.nazev as nazev_tema, clanky.id as id_clanek, clanky.nazev as nazev_clanek, precteno,id_autora,published,otvirak, DATE_FORMAT(datum_pridani, '%d. %m. %Y') as datum, temata.aktiv as aktivni_tema ,name, surname, pseudo_name, pseudo_surname,active as aktivni_autor 

FROM clanky 
join users on users.id = id_autora 
LEFT join (SELECT id_clanek, count(*) as pocet_diskuze FROM diskuze GROUP BY diskuze.id_clanek) diskuze on clanky.id = diskuze.id_clanek 
join menu on menu.id = clanky.id_tema join temata on menu.id = temata.id_tema 

WHERE published = 1 AND otvirak <> 99 and clanky.id_autora = 76 and clanky.id_tema = 21 ORDER BY clanky.nazev DESC LIMIT 0, 10

(návrh DB není můj a silně s ním nesouhlasím :))
jinak sportů je 12, ale až někomu rupne v kouli a dá jich tam řekněme 20 tak nevim nevim 20 joinů.

zkusím to s tím having, pokud se neozvej kajman nebo vysvětlím vedoucímu, že je to zbytečné.
Kajman_
Profil *
Myslím, že nic rychlejšího než group by having pro tenhle výběr neexistuje.

SELECT spolecnosti.id, nazev_cs, sum(hodnoceni) FROM spolecnosti inner join hodnoceni on spolecnosti.id = hodnoceni.id_spolecnost
WHERE id_sport in (8,11) and id_okres = 7 and id_kraj = 3 and id_typ_hotel = 5
group by spolecnosti.id, nazev_cs
having count(distinct id_sport)=2-- podle poctu cisel v zavorce
SwimX
Profil
Kajman:
wow :) děkuji.
SwimX
Profil
Po domluvě s vedoucím se rozhodlo, že se budou vypisovat společnosti nabízející i jen jednu z možností, ale upřednostnovat se budou ty, které jich nabízí víc, takže výsledný dotaz:
SELECT spolecnosti.id as id, nazev_cs, nazev_en, nazev_de, rating,  mesto,
  (SELECT typ_cs FROM typ_hotelu WHERE typ_hotelu.id = id_typ_hotel) as typ_hotelu,
  (SELECT o.nazev_cs FROM okresy o WHERE o.id = id_okres) as okres, 
  (SELECT k.nazev_cs FROM kraje k WHERE k.id = id_kraj) as kraj 
 
 FROM spolecnosti 
 inner join hodnoceni on spolecnosti.id = hodnoceni.id_spolecnost 
 
 WHERE id_sport in (4, 6, 7, 8) 
 
 GROUP BY spolecnosti.id, nazev_cs 
 
 ORDER BY count(distinct id_sport) DESC, nazev_cs DESC

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: