Diskuze: SQL dotaz pro výběr posledních zpráv

Ostatní jazyky SQL SQL a databáze SQL dotaz pro výběr posledních zpráv

Avatar
David Čápka
Tým ITnetwork
Avatar
David Čápka:

Ahoj, chtěl bych nějakým lepším způsobem vyřešit výběr soukromých zpráv zde na devbooku. V současné době je to řešené hodně v PHP, což je pomalé, chtěl bych to dostat nejlépe do jednoho databázového dotazu.

Tabulka zprava má sloupce od (id člena), komu (id člena) a text. Co potřebuji je zobrazit všechny konverzace určitého člena, tedy vždy poslední odeslanou nebo přijatou zprávu a k tomu najoinovaný nick toho s kým konverzace je. Když si kliknete na zprávy, uvidíte co myslím :)

Nějaké nápady?

Odpovědět 16.6.2013 20:21
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Jenkings:
SELECT
    uzivatele_A.nick,
    uzivatele_B.nick,
    zprava.text,
FROM zprava
JOIN uzivatele uzivatele_A ON zprava.od=uzivatele_A.id
JOIN uzivatele uzivatele_B ON zprava.komu=uzivatele_B.id;

Takhle by to asi mělo být s tím že tabulka "uzivatele" je nazev tabulky s uctama, a pocitam s tim ze tam bude sloupec "id". A sloupec "nick" zmen za nazev sloupce ve kterym je ulozeny nick.

Dotaz jsem nezkoušel, ale podle mně by to mělo fungovat

Editováno 16.6.2013 20:54
Nahoru Odpovědět 16.6.2013 20:53
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

Ono to není tak jednoduché. Potřebuji vybrat vždy jen tu poslední zprávu a ta může být buď příchozí nebo odchozí.

Nahoru Odpovědět 16.6.2013 20:55
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Odpovídá na David Čápka
Michal Žůrek (misaz):

však tam se vypisuje i datum (čas), seřaď to podle toho.

Nahoru Odpovědět 16.6.2013 20:58
Nesnáším {}, proto se jim vyhýbám.
Avatar
Jenkings
Redaktor
Avatar
Odpovídá na David Čápka
Jenkings:

no, kdybych viděl tu strukturu DB kompletně, tak bych ti to poskládal, ale takhle toho asi moc nevykoumám

Nahoru Odpovědět 16.6.2013 21:01
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

Strukturu jsem ti napsal, nic víc tam není :) Jako výsledek potřebuji kolekci posledních zpráv jednotlivým členům od určitého člena.

Nahoru Odpovědět 16.6.2013 21:03
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
David Čápka:

A ty zprávy mohou být buď příchozí (idčko člena je v od) nebo odchozí (idčko člena je v komu), je třeba vybrat tu poslední.

Nahoru Odpovědět 16.6.2013 21:04
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Odpovídá na David Čápka
Jenkings:

ale tak na to bys potřeboval u té zprávy znát buď ID, nebo čas odeslání... a pokud tam máš jen ty 3 sloupce co píšeš, tak je to dost těžký seřadit od nejnovějších

Editováno 16.6.2013 21:05
Nahoru Odpovědět 16.6.2013 21:05
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

No právě, proto sem píšu :D Tak alespoň vybrat vždy poslední zprávu z příchozích zpráv. Potom bych udělal to samé pro odchozí a propojil si to na úrovni PHP. Teď vybírám všechny, což je strašně pomalé.

Nahoru Odpovědět 16.6.2013 21:09
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Odpovídá na David Čápka
Jenkings:

dobře... okdud se bere to datum které se zobrazuje v doručených zprácách ?

Nahoru Odpovědět 16.6.2013 21:12
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

Datum je samozřejmě součástí zprávy. Promiň, na to jsem zapomněl.

Nahoru Odpovědět 16.6.2013 21:14
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Odpovídá na David Čápka
Jenkings:

moment, součástí zprávy,takže má vlastní sloupec předpokládám ?

Nahoru Odpovědět 16.6.2013 21:16
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Nahoru Odpovědět 16.6.2013 21:18
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Jenkings:
SELECT
    uzivatele_A.nick,
    uzivatele_B.nick,
    zprava.text,
FROM zprava
JOIN uzivatele uzivatele_A ON zprava.od=uzivatele_A.id
JOIN uzivatele uzivatele_B ON zprava.komu=uzivatele_B.id;
WHERE uzivatele.od=/dosazeni promenne z PHP/
ORDER BY datum DESC
LIMIT 10
Editováno 16.6.2013 21:21
Nahoru Odpovědět 16.6.2013 21:19
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

Píšu si třeba s deseti lidmi a potřebuji, aby mi dotaz ideálně vrátil 10 výsledků, kde budou vidět poslední zprávy které jsem těm lidem poslal nebo které od nich přišly. Každé řešení je lepší než současné :)

Nahoru Odpovědět 16.6.2013 21:19
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

Tohle vybere všechny zprávy ale, můžou jich být tisíce. Potřeboval bych jen těch pár posledních.

Nahoru Odpovědět 16.6.2013 21:20
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Odpovídá na David Čápka
Jenkings:

upravil jsem to ;)

stačí: LIMIT 10

Editováno 16.6.2013 21:21
Nahoru Odpovědět 16.6.2013 21:21
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

Nemyslím si, že to bude fungovat. Tohle vybere 10 posledních zpráv (klidně všechny od jednoho člověka). Já potřebuji vybrat posledních několik lidí, se kterými jsem si psal.

Nahoru Odpovědět 16.6.2013 21:26
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Odpovídá na David Čápka
Jenkings:

jo, už tomu asi začínám pomalu rozumět :D

v tom případě snad takhle:

SELECT
     uzivatele_A.nick,
     uzivatele_B.nick,
     zprava.text,
 FROM zprava
 JOIN uzivatele uzivatele_A ON zprava.od=uzivatele_A.id
 JOIN uzivatele uzivatele_B ON zprava.komu=uzivatele_B.id;
 WHERE uzivatele.komu=/dosazeni id "komu" z PHP/
 ORDER BY datum DESC
 LIMIT 10
Nahoru Odpovědět 16.6.2013 21:27
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Nahoru Odpovědět 16.6.2013 21:29
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Odpovídá na David Čápka
Jenkings:

není, změní se podmínka WHERE

Nahoru Odpovědět 16.6.2013 21:29
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

To je pořád stejné, jen to vybere posledních 10 příchozích zpráv, opět klidně všechny od jednoho člověka. Zkusím se nad tím ještě zítra nějak zamyslet :( Kit by nevěděl?

Nahoru Odpovědět 16.6.2013 21:37
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jenkings
Redaktor
Avatar
Odpovídá na David Čápka
Jenkings:

no, asi pořád nějak špatně chápu o co přesně ti jde, jinak MySQL pro mně není problém (alespoň si to myslím) , ale zítra si to pročtu znova a snad to už pochopím správně

Nahoru Odpovědět 16.6.2013 21:38
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
Jenkings
Redaktor
Avatar
Jenkings:

Ááááá už asi vím....

GROUP BY zprava.od

Editováno 16.6.2013 21:44
Nahoru Odpovědět  +1 16.6.2013 21:42
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Hynek
Redaktor
Avatar
Odpovídá na David Čápka
David Hynek:

ty tu tabulku máš bez sloupce ID? Jak pak mažeš určitou zprávu?
Ten výběr by byl s tím sloupcem ID také jednodušší, stačilo by vybrat posledních X ID s podmínkou, že OD a KOMU by byl uživatel.

Nahoru Odpovědět 16.6.2013 22:27
Čím víc vím, tím víc věcí nevím.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Věděl, už jsem něco podobného řešil. Podívám se na to zítra u PC.

Nahoru Odpovědět 16.6.2013 22:42
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Hynek
Kit:

ID je až ve 3NF. Každému se normalizovat nechce.

Nahoru Odpovědět 16.6.2013 22:49
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
vodacek
Redaktor
Avatar
 
Nahoru Odpovědět  +1 17.6.2013 8:18
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jenkings
David Čápka:

Grouping mě také napadlo, ale nevím jak zadat že chci v každé skupině jen tu nejposlednější zprávu. Já sem za chvíli hodím nějaký obrázek, aby to bylo lépe představitelné.

Nahoru Odpovědět 17.6.2013 9:11
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na vodacek
David Čápka:

Jo, to mě taky napadlo. Vybrat si distinctem IDčka lidí se kterými jsem si psal a potom vybrat ke každému IDčku nejposlednější zprávu. To druhé ale nevím jak udělat, když tam dám:

select *
from zprava
where od in (select distinct...) or komu in (select distinct...)
order by datum desc
limit 1

Tak mi to vybere jeden výsledek pokud se nepletu.

Editováno 17.6.2013 9:14
Nahoru Odpovědět 17.6.2013 9:14
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

On je to docela problém, protože porušuješ 2NF. Dotaz bude o to složitější. Nejprve si to vyzkouším a pak to sem pošlu.

Nahoru Odpovědět  +1 17.6.2013 9:35
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Můžeme to zjednodušit na ten distinct. Dejme tomu, že si uložím výsledek tohoto dotazu:

select distinct komu
from zprava
where komu = id_clena

Od toho by se asi dalo odpíchnout, mám idčka těch, se kterými jsme si psal. Jak mohu následně vybrat kolekci nejnovějších příspěvků s lidmi s tímto ID? Asi tam bude figurovat nějaký poddotaz, ale nenapadá mě jak to udělat.

Editováno 17.6.2013 9:55
Nahoru Odpovědět 17.6.2013 9:54
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Nebo tam mohu přidat tabulku konverzace a denormalizovat to, ale tomu bych se chtěl vyhnout, protože bych se musel při odeslání každé zprávy zase ptát countem jestli existuje konverzace (mohu psát někomu, s kým jsem si ještě nepsal). Proto to zde není udělané jako na fóru, kde je to jednoduše denormalizování přes tabulku vlakno.

Nahoru Odpovědět 17.6.2013 10:02
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Spíš normalizovat. V jedné tabulce mít zprávy s id a timestampem, ve druhé seznam odesílatelů a příjemců s cizím klíčem na zprávy. Výhodou bude, že příjemce si nežádoucí zprávu bude moct smazat nezávisle na odesílateli.

Bohužel MySQL neumí cizí klíče, takže mazání textu zpráv je o něco složitější.

Nahoru Odpovědět 17.6.2013 10:08
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Nějak v tom nevidím tu výhodu, problém mi přijde úplně stejný, jen musím ještě joinovat.

Nahoru Odpovědět 17.6.2013 10:12
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Ono to řeší spíš navazující problémy. Však počkej chvilku, než se k tomu PC dostanu.

Nahoru Odpovědět 17.6.2013 10:17
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Dobře, díky :) Jsme na to zvědavý, protože já opravdu netuším. Uměl bych to udělat jedině tak, že bych v cyklu volal selecty na poslední zprávu, což není asi ideální.

Nahoru Odpovědět 17.6.2013 10:18
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Tak to není ideální ani náhodou. Zejména pokud takový report potřebuješ vypsat každou chvilku. Jeden trochu složitější select musí stačit.

Editováno 17.6.2013 10:21
Nahoru Odpovědět 17.6.2013 10:20
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Redaktor
Avatar
Nahoru Odpovědět 17.6.2013 15:44
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Dnes mi to nějak nemyslí, sesmolil jsem tohle:

SELECT * FROM (
    SELECT * FROM (
            SELECT cas, komu AS partner, zprava FROM chat WHERE od=:od
        UNION ALL
            SELECT cas, od AS partner, zprava FROM chat WHERE komu=:komu
        ) AS schat ORDER BY cas DESC
    ) AS sschat
    GROUP BY partner ORDER BY cas DESC LIMIT 10;

ale netuším, jak moc to bude rychlé. Ani jsem netestoval, zda je to funkční.

Nahoru Odpovědět 17.6.2013 16:23
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Dobře, dnes jsem zahlcený články, zítra se do toho pustím :)

Nahoru Odpovědět 17.6.2013 16:28
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Nějak se tomu nechce: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from=:from UNION ALL". Nelíbí se tomu ta dvojtečka. Poslal jsem ti to celé do PM, nechci to tu vystavovat.

Nahoru Odpovědět 18.6.2013 10:58
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Ta dvojtečka funguje jen v prepared statements. Nahrazuje ošklivě znějící funkci mysql_real_escape_string() a zpřehledňuje zápis SQL dotazu. Starý ovladač MySQL s tím pracovat neumí, ale jede to v MySQLi a PDO.

Běžně místo :od používám otazník, který však funguje pozičně.

Nahoru Odpovědět 18.6.2013 11:04
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Jelikož devbook zatím jede na té pitomé dibi, tak to zatím použít nemohu :-/ Je nějaký způsob, jak bych to mohl teď zprovoznit? Pokusím se té dibi co nejdříve zbavit, neskutečně mě omezuje ve všech ohledech.

Nahoru Odpovědět 18.6.2013 11:38
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Napsal jsem ti to přece v PM.

Tohle je jeden z důvodů, proč se mi nelíbí ORM frameworky. Buď jsou primitivní a skoro nic neumí, anebo jsou to molochy, které i jednoduché úkoly řeší stylem "kanón na vrabce". Než abych přemýšlel, co to udělá s SQL, raději si to SQL napíšu sám.

Něco se dá řešit i přes pohledy. Dibi s takovým pohledem bude zacházet jako s běžnou tabulkou.

V tom řešení jsem vlastně ani nepopsal vazbu na tabulku nicků. Byl to jen takový hrubý nástřel, abys měl nad čím přemýšlet. MySQL má v dotazech poddobného typu poměrně omezené možnosti a není úplně jednoduchá najít správné a přitom i efektivní řešení. Třeba na něco elegantního během dne přijdu, ale v tuto chvíli bych jen doladil dotaz, který jsem už poslal.

Místo :from a :to se dosadí ID uživatele, přo kterého hledáš ty poslední zprávy.

Nahoru Odpovědět  +1 18.6.2013 11:53
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Nojo, mě to nedošlo, používám vždycky otazník a zapomněl jsem, že to jde i takhle. Ten dotaz funguje, zdá se být i dostatečně rychlý :)

Nad vazbou na uživatele přemýšlím, předpokládám, že na to bude nějaký korelovaný poddotaz, ale nedaří se mi na to přijít.

Nahoru Odpovědět 18.6.2013 12:31
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 46 zpráv z 46.