Diskuze: Přátelství
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 28 zpráv z 28.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Napadli mě 2 možnosti, ale dlouho jsme nepřemýšlel a tak možná budou i lepší řešení.
$pole[] = explode(",",$sloupec);
si vytvoříš pole ale, musíš vytvářet další dotaz na výpis uživatelů dle id, stejně tak v příkladu 1.
Nejlepší řešení dle mě je příklad 1, kde si doplníš do DB vše co se toho týká joineš to s uživatelem a máš to jako 1 dotaz a kdykoliv
Databází jsem myslel tabulku. **
Mám takový dojem, že tuhle vazbu má vyřešenou. Jestli jsem dotaz pochopil správně, tak by chtěl dotazem vrátit uživatele, kteří se navzájem odebírají právě z tabulky odběratele, kterou popsal v dotazu. Je to tak?
Pravda, prakticky jsem napsal to co již má a špatně pochopil dotaz.
Záleží k čemu to přesně potřebuje a jak to přesně potřebuje. K
čemu je porovnávat vazbu mezi všemi odběrateli.
Ale pakliže potřebuji zjistit vazbu mezi všemi, tak je nutné se všech
zeptat. nebo si postupně vytvářet evidenci.
Pakliže potřebuje zjistit společné odběratele mezi tím na koho se např. zrovna budu dívat, tak to je jednoduché a to předpokládám, že není ono. Protože pak je to porovnání jen 2 ID .
Ahoj,
nějak mi to nedalo spát a tak jsem dal něco dohromady.
Snad je to, co si chtěl .
Jak chceš ty uživatele získat? Resp. jaký má být výstup? Podle toho, co píšeš, chceš z jedné tabulky dva výstupy, jak chceš ty výstupy potom porovnávat?
A co mít tabulku, kde bude followId, aUserId, bUserId, aFollows, bFollows.
Uživatele budeš přidávat do tabulky, tak třeba ten s nižším id bude A, druhý B. No a pak jenom hodíš select where aFollows je true a bFollows je true.
Začínám si uvědomovat, že tak moc šikovný to není. Ale jenom na to, co tady píšeš, by to bylo fajn
Takhle to fungovat nebude. Viz. http://sqlfiddle.com/#…
Martin Štěpánek Ten návrh tabulky je špatně, stačí jenom id_kdo a id_koho, nic víc. Ani tam nemusíš mít žádné speciální ID jako primární, jednoduše použiješ kompozitní klíč. Pokud například potřebuješ získat všechny "přátele" na profilu konkrétního uživatele, tak to není zas tak těžké. Viz. upravená verze dotazu od Tukmak http://sqlfiddle.com/#… pro uživatele s ID 1. Pokud chceš kompletní výpis přátel, tak můžu během dneška něco vyzkoušet, mám v hlavě několik řešení, ale nevím jak moc jsou použitelné.
Ty nicky a Id tam mam jen abych nemusel spojovat tabulky.
Kdyby jsi byl tak hodný, byl bych ti vděčný.
Potřebuji to tak, že když se budou dva lidé navzájem odebírat, stanou se
přáteli. A já potřebuji, aby se každému uživateli po přihlášení
vypsal seznam jeho přátel. Tedy vlastně nick_koho.
Nestačilo by tedy něco na způsob :
$query = mysql_query("SELECT * FROM odebirani WHERE id_koho = ".$idPrihlasenehoUzivatele);
while($odberatel = mysql_fetch_object($query){
echo $odberatel->nick_kdo;
}
?
Ovládač mysql sa už nemá používať, náhrada zaň je mysqli alebo ešte bezpečnejšie PDO
Však já vím, říkám něco na ten způsob. Spíše mi šlo o to, jestli dobře chápu, co vlastě chce.
http://sqlfiddle.com/#… Tohle by mělo být přesně ono. V PHP pak akorát dosazuješ ID uživatele na do ON u prvního joinu místo 1.
To nejde protože to vypíše jen ty co odebírá uživatel, ne ty, kteří se odebírají navzájem.
jde to udělat hezky a jednoduše přes SQLko (aby se neřeklo, tak souhlasím s tím, že je to piplačka).
CREATE DATABASE pratelsky_spolek
CHARACTER SET utf8
COLLATE utf8_czech_ci;
USE pratelsky_spolek;
CREATE TABLE clovek (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id),
nick VARCHAR(255) NOT NULL
);
CREATE TABLE odberatel (
odebiratel INT NOT NULL,
odebirany INT NOT NULL,
PRIMARY KEY (odebiratel, odebirany),
FOREIGN KEY (odebiratel) REFERENCES clovek (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (odebirany) REFERENCES clovek (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
INSERT INTO clovek (nick) VALUES
('Karl'),
('Tom'),
('SweetCandy'),
('Strawberry'),
('World king');
INSERT INTO odberatel (odebiratel, odebirany) VALUES
(1, 2), -- --------|
(1, 4), -- --------+----|
(2, 4), -- | |
(3, 2), -- --------+----+----|
(2, 1), -- --------| | |
(3, 1), -- | |
(4, 1), -- -------------| |
(3, 4), -- |
(4, 5), -- |
(2, 3); -- ------------------|
SELECT *
FROM odberatel as p
WHERE p.odebiratel = ? and p.odebirany IN
(
SELECT odebiratel
FROM odberatel
WHERE odberatel.odebirany = ?
);
Nejpodstatnější je asi poslední SELECT, místo otazníku dej id uživatele, od kterého chceš dostat s kým se oboustranně přátelí.
pak si to samozřejmě můžeš vyšperkovat JOINem.
SELECT p2.nick AS odberatel, p1.nick as odebirany
FROM odberatel as p
JOIN clovek AS p1 ON p.odebirany = p1.id
JOIN clovek as p2 ON p.odebiratel = p2.id
WHERE p.odebiratel = ? and p.odebirany IN
(
SELECT odebiratel
FROM odberatel
WHERE odberatel.odebirany = ?
);
Ad 2. Za otazníky musíš pro správnou funkčnost doplnit stejné ID.
Vypadá to pro mě jako začátečníka v SQL šíleně, ale moc děkuji.
tak ty základní příkazy, CREATE TABLE, CREATE DATABASE, INSERT INTO, USE asi chápeš, možná cizí klíče při vytváření tabulky odberatel, ale kdybys je nenapsal, konec světa nenastane. Složitější je možná pak už jen ten select, který v podmínce ošetří aby to fungovalo oboustranně. V podstatě se jedná o to že to skontroluje pokud to funguje A => B a pak jestli A je na seznamu těch, které odebírá B. Čili A <==> B. Ten JOIN je vlastně to samé, jen to tam připojí nicky. Až to budeš používat ještě si sprav, že mi tam někde uniklo, že as a and jsou malými písmeny
Super a můžeš mi ještě jen vysvětlit co dělá ten dotaz při vytváření tabulky odberatel?
... FOREIGN KEY (odebiratel) REFERENCES clovek (id)
ON DELETE CAS....
ten nastavuje ty cizí klíče. V podstatě databázi řekne, že sloupeček odebiratel odkazuje do tabulky clovek na sloupeček id a databáze ti nedovolí tam vložit číslo, které není id nějakého člověka. Další dva řádky říkají, co se má stát, když dojde k smazání vázaného záznamu v tabulce clovek.CASCADE říká, že když řádek smažu, smaže se i v tabulce odebiratel (jinými slovy když smažu člověka, tak se smažou všechny záznamy odebíraní, kde je uveden). To samé platí pro změnu, když změním id uživatele na všech záznamech se změní.
V podstatě jde jen o to, že když bys tam v tomto okamžiku spustil příkaz
INSERT INTO odberatele (odberatel, odebirany) VALUES (1, 100)
tak ti to vyhodí chybu, protože nikdo s číslem 100 tam není. To ON UPDATE a ON DELETE je jen třešnička na dortu.
Elegantní řešení, krásná ukázka jak dobře pracuje MySQL a jak lze
spoustu věcí udělat díky ní, aniž by člověk použil některé podmínky
v php, nebo další dotazy. Opravdu pěkné !
Ale zdá se mi jinak, že jsem to prvně pochopil správně a jen si to napsal
po svém, tedy s myšlenkou úplně stejnou, ale bez nějaké ukázky.
Taky jsem si to zkusil vyřešit. Myslím, že jsem došel ke stejnému cíli
trochu jinou cestou než misaz.
V zadání se píše "výpis uživatelů, kteří se odebírají navzájem":
Takže všechny tyto uživatele bych si z tabulky od misaz vytáhl takto:
SELECT p1.* FROM odberatel p1
WHERE p1.odebirany = (SELECT p2.odebiratel FROM odberatel p2 WHERE p2.odebirany = p1.odebiratel
AND p2.odebiratel = p1.odebirany)
AND p1.odebiratel < p1.odebirany
Pokud chci jednoho konkrétního uživatele, tak jako vyřešil misaz, upravím jen trochu podmínky:
SELECT p1.* FROM odberatel p1
WHERE p1.odebirany = (SELECT p2.odebiratel FROM odberatel p2 WHERE p2.odebirany = p1.odebiratel
AND p2.odebiratel = p1.odebirany)
AND p1.odebiratel = ?
phpMyAdmin vrací výsledek mého dotazu a zanedbatelnou tisícinku
rychleji.
Třeba při větší tabulce by už to tak zanedbatelné nebylo
Jinak super web! Objevil jsem to tu nedávno. Zrovna se prokousávám tutoriály o OOP v PHP.
Zobrazeno 28 zpráv z 28.