Autor Zpráva
danhill
Profil
Dobrý den,
vím,že je tady desítky vláken na tohle téma. Ale nějak mi to hlava nebere. Nejsem schopen sestavit dotaz přes dvě tabulky.
V jedné tabulce mám :
[final] (id,date,user,code,name,lat,lon)

A v druhé tabulce jsou oblíbené
[favorite] (id,user,code)

Uživatel si přidá řádek z final do oblíbených podle code.
A já potřebuji vytvořit tabulku final,ale pouze s oblíbenými daného uživatele.

Zkoušel jsem něco jako
$select = $mysqli->query("SELECT * FROM `final`a INNER JOIN favorite b ON a.user = b.user AND a.user = '".$userID."' ORDER BY date DESC);
Ale to se mi uplně pomotá dohromady a nevím jak z toho ven :(

Moc děkuji za pomoc.

PS. omlouvám se, že jsem vložil dotaz do vlákna PHP - asi je to spíše dotaz do MYSQL... Nevšiml jsem si.
juriad
Profil
Chápu to správně tak, že uživatelé si na mapě naklikají nějaké body (tabulka final) a některé z těch bodů si mohou označit za oblíbené?

SELECT fi.*
FROM final fi
INNER JOIN favorite fa ON fi.user = fa.user AND fi.code = fa.code
WHERE fa.user = $userID
ORDER BY fi.date DESC

Chyba je v tom, že do klauzule ON patří jen spojovací podmínka, nikoli filtrovací.
UserId je nejspíš číslo, ne? Takže by nemělo být obaleno apostrofy.
danhill
Profil
Ano ano, přesně tak je to číslo a chápeš správně ..
$userID je ID právě přihlášeného uživatele.
Wooow, čumím, já to zkouším už asi čtyři hodiny a nic ... Chodí to ... Jen jsem musel upravit trošku :
SELECT fi.* 
FROM final fi 
INNER JOIN favorite fa ON fi.code = fa.code 
WHERE fa.user = $userID 
ORDER BY fi.date DESC

Protože ID uživatele který bod vložil je v tomto případě vlastně uplně jedno :)

Moc děkuji za pěkný vánoční dárek.
A přeji veselé Vánoce a mnoho štěstí do nového roku.
midlan
Profil
Jestli je to v MySQL tak apostrofy u čísla by vadit neměly. Ale proč píšu: nevidím tam ošetření proti SQL injection. Možná si v tomto případě můžeš být relativně jistý, že tam bude číslo, ale dobrým zvykem je escapovat všechno, i když jsou to programová data (a ne od uživatele).
lionel messi
Profil
midlan:
Absolútny súhlas, len doplním, že pokiaľ ide o číslo, postačí namiesto escapovania pretypovanie (napr. pomocou intval). :-)
Keeehi
Profil
lionel messi:
že pokiaľ ide o číslo, postačí namiesto escapovania pretypovanie
A jak jinak by jsi chtěl escapovat číslo? mysql_real_escape_string() by ti v tomto případě nepomohl.
midlan
Profil
Keeehi:
Pomohl. Jak jsem napsal, v MySQL by nemělo vadit číslo v apostrofech, takže bych tu funkci klidně použil i na čísla.
Keeehi
Profil
Ano, vkládat číslo jako string můžeš, MySQL si to automaticky zkonvertuje na float. Nepřipadá mi to však jako dobrá technika.
midlan
Profil
Toť už pak na každém jak se mu to líbí. Já preferuji způsob používání escapovací funkce všude, tzn. i na čísla. Přijde mi to tak konzistentnější než ji střídat s floatval a intval.
Keeehi
Profil
midlan:
A když je ve sloupci povolené mít null? To už v uvozovkách být nemůže a konzistence je v čoudu. Stejně nejlepším řešením je to celé nechat na nějaké knihovně, která se automaticky vždy a korektně o escapování postará. Nedá se pak na escapování zapomenout a to ani omylem.
midlan
Profil
S tím nelze než nesouhlasit :)
danhill
Profil
Pár měsíců uplynulo a řeším podobný problém opět si nevím rady.
Mám dotaz :
SELECT gc_code,user, 
COUNT(gc_code) AS pocet 
FROM final 
WHERE live!=2 AND group_id=2 
GROUP BY user ORDER BY pocet DESC, user

Problém je, že sloupec group_id je v jiné tabulce.
Tahle nová tabulka vypadá takto : [usergroup_map] (user_id,group_id)

Situace je taková, že user = user_id
A dotaz má spočítat gc_code každého uživatele, který je ve skupině group_id=2 a seřadit podle největšího počtu gc_code

Mé pokusy jako např:
SELECT fi.gc_code,fi.user,
COUNT(fi.gc_code) 
AS pocet
FROM final fi 
INNER JOIN usergroup_map gr ON fi.user = user_id 
WHERE fi.live!=2 AND gr.group_id=2
GROUP BY user ORDER BY pocet DESC, user
Končí marně ...


Ha ... tak asi jsem to vyřešil ... ten pokus co jsem uvedl funguje :D ...
Takže asi dobrý ...
I tak děkuji :) .
juriad
Profil
Já myslím, že ten tvůj dotaz by měl fungovat. Jen jsem ho malinko učesal (žádné funkční rozdíly):
SELECT fi.user, COUNT(fi.gc_code) AS pocet
FROM final fi 
JOIN usergroup_map gr ON fi.user = gr.user_id
WHERE fi.live != 2 AND gr.group_id = 2
GROUP BY fi.user
ORDER BY pocet DESC, fi.user ASC

Co na něm nefunguje? Nespustí se? Jakou chybu vypíše? Vrací něco, co nemá? Nevrací něco, co má?

Pozor: ten tvůj dotaz vrací pro každéh uživatele jeho ID, počet gc_code a nějaký náhodný gc_code. To asi není vhodné, proto jsem jej odstranil.
danhill
Profil
Nádhera ... Moc děkuji ... tohle určitě vypadá hezčeji ... Ano funguje i ten můj,ale divně chodil, právě ...
Děkuji moc ... Krásně to vypadá, ted.
danhill
Profil
Protože již vím, že jste tady opravdu dobří na tyhle dotazy přes více tabulek,
potřeboval bych poslední dotaz, který jsme zde sestavili ještě trochu rozšířit.
A sice k požadovanému "počet" ještě přičíst hodnotu z další tabulky - a sice počet poděkovaní v diskuzním foru.
Samostaně mi to funguje:
SELECT thx.userid, COUNT(thx.userid) AS count_thx
FROM kunena_thankyou thx
JOIN user_usergroup_map gr ON thx.userid = gr.user_id
WHERE gr.group_id = 2
GROUP BY thx.userid
ORDER BY count_thx DESC, thx.userid ASC

Z toho dostanu krásně sloupec count_thx seřazený stejně jako v předchozím dotazu sloupec pocet
Ale potřeboval bych aby se mi vždy count_thx sečetl se sloupcem pocet daného uživatelského ID (v jedné tabulce je to sloupec user , v druhé user_id a ve třetí userid

Respektive, možná ani nepotřebuji aby se to sčítalo už přímo v dotazu,ale výsledný array by měl obsahovat vždy řádek s uživatelským ID s počtem GC_code a s počtem poděkování.

No snad jsem to vysvětlil nějak jako srozumitelně ...

Jen dodám, že je to z toho důvodu, že uděluji uživatelů body na webu za jejich aktivitu jak přidáváním GC_code, tak aktivitou na diskuzním foru a za každé obdržené poděkování a za každý vložený GC_code obdrží body.
Záreoveň zůstává podmínka WHERE fi.live != 2 AND gr.group_id = 2 .
Výsledkem totohoto dotazu je žebříček uživatelů od nejaktivnějšího k nejméně aktivnímu.
danhill
Profil
Tak v pohodě ... vyřešil jsem to jednoduše druhým dotazem ve foreach prvního dotazu a hodnoty prostě sečetl ... Chodí to dobře.
Takže netřeba řešit.
Děkuji i tak :)
juriad
Profil
Přijde mi, že chceš provést spíš něco jako toto:
SELECT gr.user_id, f.finals, t.thanks, f.finals + t.thanks AS total
FROM user_usergroup_map gr # tabulka uživatelů
LEFT JOIN ( # počty finálek
  SELECT fi.user, COUNT(fi.gc_code) AS finals
  FROM final fi
  WHERE fi.live != 2
  GROUP BY fi.user
) f ON gr.user_id = f.user
LEFT JOIN ( # počty díků
  SELECT thx.userid, COUNT(thx.userid) AS thanks
  FROM kunena_thankyou thx
  GROUP BY thx.userid
) t ON gr.user_id = t.userid
WHERE gr.group_id = 2 # filtrace uživatelů
ORDER BY total DESC, gr.user_id ASC
danhill
Profil
Ano ano, moc děkuji, tohle je přesně co jsem chtěl.
Jen to má jednu chybičku.
Pokud uživatel nemá,žádné poděkování na foru,ale má vložené finálky nedojde k sečtení,protože sloupec thanks obsahuje hodnotu NULL a tedy i total je pak NULL a není tedy zařazen do žebříčku...
Jak to napravit?


Jo, asi jsem na to přišel:
SELECT gr.user_id, IFNULL(f.finals,0), IFNULL(t.thanks,0), IFNULL(f.finals,0) + IFNULL(t.thanks,0) AS total

Teď bych řekl,že to chodí perfektně ...
Děkuji moc.

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: