Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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

Aktivity
Avatar
David Hartinger
Vlastník
Avatar
David Hartinger:16.6.2013 20:21

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
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Jenkings:16.6.2013 20:53
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 Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 20:55

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
You are the greatest project you will ever work on.
Avatar
Odpovídá na David Hartinger
Michal Žůrek - misaz:16.6.2013 20:58

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

 
Nahoru Odpovědět
16.6.2013 20:58
Avatar
Jenkings
Tvůrce
Avatar
Odpovídá na David Hartinger
Jenkings:16.6.2013 21:01

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 Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 21:03

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
You are the greatest project you will ever work on.
Avatar
David Hartinger
Vlastník
Avatar
David Hartinger:16.6.2013 21:04

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
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Odpovídá na David Hartinger
Jenkings:16.6.2013 21:05

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 Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 21:09

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
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Odpovídá na David Hartinger
Jenkings:16.6.2013 21:12

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 Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 21:14

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

Nahoru Odpovědět
16.6.2013 21:14
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Odpovídá na David Hartinger
Jenkings:16.6.2013 21:16

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 Hartinger
Vlastník
Avatar
Nahoru Odpovědět
16.6.2013 21:18
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Jenkings:16.6.2013 21:19
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 Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 21:19

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
You are the greatest project you will ever work on.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 21:20

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
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Odpovídá na David Hartinger
Jenkings:16.6.2013 21:21

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 Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 21:26

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
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Odpovídá na David Hartinger
Jenkings:16.6.2013 21:27

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 Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 21:29

Vždyť je to stejné :D

Nahoru Odpovědět
16.6.2013 21:29
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Odpovídá na David Hartinger
Jenkings:16.6.2013 21:29

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 Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:16.6.2013 21:37

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
You are the greatest project you will ever work on.
Avatar
Jenkings
Tvůrce
Avatar
Odpovídá na David Hartinger
Jenkings:16.6.2013 21:38

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
Tvůrce
Avatar
Jenkings:16.6.2013 21:42

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

GROUP BY zprava.od

Editováno 16.6.2013 21:44
Nahoru Odpovědět
16.6.2013 21:42
Největší časovou náročnost má výpočet časové náročnosti..
Avatar
David Hynek
Tvůrce
Avatar
Odpovídá na David Hartinger
David Hynek:16.6.2013 22:27

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
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:16.6.2013 22:42

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
Tvůrce
Avatar
Odpovídá na David Hynek
Kit:16.6.2013 22:49

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
Tvůrce
Avatar
Odpovídá na David Hartinger
vodacek:17.6.2013 8:18

prdni tam distinct

 
Nahoru Odpovědět
17.6.2013 8:18
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Jenkings
David Hartinger:17.6.2013 9:11

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
You are the greatest project you will ever work on.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na vodacek
David Hartinger:17.6.2013 9:14

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
You are the greatest project you will ever work on.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:17.6.2013 9:35

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
17.6.2013 9:35
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:17.6.2013 9:54

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
You are the greatest project you will ever work on.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:17.6.2013 10:02

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
You are the greatest project you will ever work on.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:17.6.2013 10:08

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 Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:17.6.2013 10:12

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
You are the greatest project you will ever work on.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:17.6.2013 10:17

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 Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:17.6.2013 10:18

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
You are the greatest project you will ever work on.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:17.6.2013 10:20

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
Tvůrce
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
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:17.6.2013 16:23

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 Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:17.6.2013 16:28

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

Nahoru Odpovědět
17.6.2013 16:28
You are the greatest project you will ever work on.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:18.6.2013 10:58

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
You are the greatest project you will ever work on.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:18.6.2013 11:04

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 Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:18.6.2013 11:38

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
You are the greatest project you will ever work on.
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:18.6.2013 11:53

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
18.6.2013 11:53
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:18.6.2013 12:31

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
You are the greatest project you will ever work on.
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.