Autor Zpráva
nevimjak
Profil *
Zdravim, měl bych dotaz, jak nejlépe provést provázanost tabulek (v DB SQLite).
1.mám tabulku , která má sloupce autor_id (*jedinečné id),jmeno
2.mám tabulku , která má sloupce tema_id (*jedinečné id),popis,autor_id, (datum,pocet)
3.mám tabulku , která má sloupce tema_id,text,autor_id,datum

jde mě o to, že potřebuji vypsat (aktualizovat) obsah tabulky2 s tím, že pro jedinečný záznam tema_id se vypíše počet záznamů v tabulce3 a datum posledního záznamu v tabulce3.
Teď to provádím tak, že jetliže provedu insert záznamu do tabulky3, provedu update hodnot datum a pocet (pocet+1) v tabulce2 dle tema_id.
Tak se ptám, jestli je jiné jak to udělat? Asi v případě výpisu tabulky2 nasčítat pocet a zjistit posledni datum pro tema_id, jenže takový select si neumím ani představit a také jestli není rychlostně náročný (již teď přiřazuji dle autor_id jmeno).
Není ještě jiné řešení? Je to v podstatě diskusní forum, tabulka uzivatelu,temat a prispevku.
Děkuji za rady
nevimjak
Profil *
Nešlo by nějak použít trigger? Ještě jsem to nikdy neaplikoval, tak se chci zeptat jestli to je možné a jak? Tzn. že při vložení záznamu do tabulky3 by se automaticky updatoval sloupec datum a pocet v tabulce2 dle tema_id
Děkuji za radu
juriad
Profil
nejlépe asi tím triggerem
CREATE TRIGGER nazevTriggeru AFTER INSERT ON tabulka3
    WHEN 1=1 -- vzdy
    BEGIN
        UPDATE tabulka2 SET pocet = pocet+1, datum = new.datum WHERE tema_id = new.tema_id;
    END;
nevimjak
Profil *
Tak tohle je úplně přesně to, co jsem potřeboval! Samozřejmě to budu obdobně aplikovat i pro delete.
Pane 'juriad' móc děkuji za radu, móc mě to pomohlo
juriad
Profil
ten dotaz do tabulky 2 bez sloupců datum a počet není moc složitý:
SELECT t2.tema_id, t2.popis, t1.jmeno, count(t3.prispevek_id) AS pocet, max(t3.datum) AS datum
FROM tabulka2 AS t2 
JOIN tabulka3 AS t3 ON t2.tema_id = t3.tema_id
JOIN tabulka1 AS t1 ON t2.autor_id = t1.autor_id
GROUP BY t2.tema_id
nevimjak
Profil *
No, na mě už teda je takový dotaz náročný je:-) Druhá věc, není náročný na zpracování (samozřejmě pří mnoha záznamech)?
Myslím si,že to řešení pomocí triggeru je elegantní. V kažkém případě, člověk se stále učí.....
Tomáš K.
Profil *
Řešení pomocí triggerů je nestandardní - je to víc práce vytvořit, potenciální zdroj chyb, sloupce navíc zabírají nějaké (zpravidla nevýznamné) místo, zpomaluje to INSERT, DELETE. Zpravidla se to řeší dotazem, se vhodnými indexy (viz např. google 'mysql index') to je rychlé.
nevimjak
Profil *
Jěště dotaz, je mě jasné, že to lze udělat přímo při vlastním UPDATE, ale optám se.
mám tabulku TAB a v ní sloupce ID, JMENO, ZMENA. Jde pomoci triggru automaticky zmenit datetime v ZMENA, jestliže jsem provedl update ID nebo JMENO ?
Děkuji za info
juriad
Profil
CREATE TRIGGER nazevTriggeru AFTER UPDATE ON tab
    WHEN new.id != old.id OR new.jmeno != old.jmeno -- kdyz se zmeni id nebo jmeno
    BEGIN
        UPDATE tab SET zmena = datetime('now', 'localtime') WHERE id = new.id;
    END;
podmínka when je nutná, jinak by se trigger zacyklil

nikdy bys neměl měnit id, má to snad jen nevýhody, také nebudeš člověku měnit rodné číslo
Tomáš K.
Profil *
nevimjak:
Nastavte sloupec jako zmena TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
nevimjak
Profil *
podmínka when je nutná, jinak by se trigger zacyklil
jasně, pravě to jem si říkal, že by mohlo dojít k zacyklení, vyzkouším, děkuju

Ještě jedem dotaz k selectu ze dvou tabulek:
TAB1 [id (text), typ (char1), kod (text), rok (datetext)]
TAB2 [kod (text), jmeno (text), rok1 (datetext), rok2 (datetext)]
obsah TAB1:
pepa, J, kovolis, 1980
pepa, S, montaz, 1986
pavel, R, obroba, 1966
pepa, R, kovolis, 1954
pepa, S, montaz, 2003
pepa, J, kovolis, 2000
obsah TAB2
kovolis, Lisovna Brno, 1950, 1979
kovolis, Kovolis Brno, 1980, 1983
kovolis, Lisovna Brno, 1984, 2009
montaz,Montazovna Lipa, 1980, 1986
montaz,Montaz Borova, 1987, 2011
obroba,Skoda Plzenov, 1955, 1960

potreboval bych udelat vypis z TAB1 pro id=pepa
1. razeno dle typ J, S, R
2. razeno dle roku 1954, 1980, 1999
3. aby kod byl zamenen z TAB2 dle roku jmenem

takže by to vypadalo asi takhle (bez id):
J, Kovolis Brno, 1980
J, Lisovna Brno, 2000
S, Montazovna Lipa, 1986
S, Montaz Borova, 2003
R, Lisovna Brno, 1954

prosím, poraďte se selectem. Moc děkuji
juriad
Profil
zkusím:
SELECT t1.typ, t2.jmeno, t1.rok
FROM TAB1 t1 JOIN TAB t2 ON t1.kod = t2.kod AND t1.rok BETWEEN t2.rok1 AND t2.rok2
WHERE id='pepa'
ORDER BY t1.typ='J' DESC, t1.typ='S' DESC, t1.typ='R' DESC, t1.rok ASC

pokud nejsou záznamy v TAB2 souvislé (kovolis, 2012), můžeš nahradit JOIN za LEFT JOIN

jestli se můj dotaz chová chybně, popiš takový příklad
nevimjak
Profil *
Děkuji, vypadá to, že dotaz pracuje přesně tak jak potřebuji. A co kdybych potřeboval vazbu ještě na třetí tabulku?
např. do TAB2 by jěště přibyl sloupec [stat (char3)] např. cze
a TAB3 [stat(char3), jmeno(text)] cze, Česko

TAB1: pepa, J, kovolis, 1980
TAB2: kovolis, Kovolis Brno, cze, 1980, 1983

pak
J, Kovolis Brno, Česko,1980

stačí přidat další JOIN t2.stat = t3.stat ?
juriad
Profil
JOIN TAB3 ON t2.stat = t3.stat

zkus si pročíst manuál
nevimjak
Profil *
Ok,je to ok.
Ještě dotaz k diakritice. Řadí mě to špatně např. Babka, Baranek, Baček .... DB SQLite, UTF-8
Jak jde řazení ovlivnit a co je nutné pro to udělat? Děkuji za radu
juriad
Profil
jde to ovlivnit opravdu špatně:
používá se na to klíčové slovo COLLATE v ORDER BY
v sqlite existují podle dokumentace jen 3: http://www.sqlite.org/datatype3.html#collation
existuje patch do php, který umožňuje přidat vlastní collation sequence: https://bugs.php.net/bug.php?id=60871, ale nevím, jestli je široce rozšířený

výsledek je, že to spíš nejde
můžeš ale použít workaround: vytvoř si další sloupec, který bude obsahovat jména bez diakritiky, potom řaď podle něj, budou to lepší výsledky, ale spousta režie navíc
nevimjak
Profil *
DB SQLite, UTF-8
Ještě se zeptám opačně, mám sloupeček s diakritikou, a chci aby se podle něj sortovalo, ale jako by bez diakritiky.
Takže asi nejschůdnější je udělat ještě sloupeček bez diakritiky? Nebo řešil to již někdo z Vás jinak?
Děkuji za pomoc

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:

0