Autor Zpráva
T-fon
Profil
Ahoj, mám 3 tabulky: uzivatele(id,jmeno,...), kategorie(id,nazev) a uzivkat(id_uzivatele,id_kategorie). Uživatel může být zařazen ve více kategoriích. Jaký je nejelegantnější způsob výpisu dotazu na konkrétního uživatele?
Zkusil jsem tyto možnosti:
- všechny 3 tabulky spojit pomocí JOIN. Pak vypsat pomocí cyklu while, s tím, že při prvním běhu vypíšu uživatele i kategorie a v ostatních už jen kategorie
- udělám 2 dotazy, v prvním jen výpis uživatele a ve druhém spojím ostatní tabulky a vypíšu pomocí while
Poprosil bych o radu, jestli jsou tabulky dobře navržené a jestli není nějaká jednoduší možnost vypsání.
Alphard_
Profil *
Cílem je výpis seznamu uživatelů a uvést, do kterých kategorií každý z nich patří?
Struktura je navržená dobře a obě navržené možnosti, jestli je správně chápu, jsou v pořádku. Kdyžtak uveďte příklad požadovaného výpisu. První dotaz je asi víc typický pro ručně psaný model, 2 dotazy s where in () pro ORM systémy.
Tomášeek
Profil
T-fon:
Správnéřešení jsou tři tabulky tak, jak je máš, a jeden dotaz.

S tím cyklem jsem to nepochopil. Bude tam jeden cyklus, v němž si budeš pamatovat posledního vypsaného uživatele a porovnávat se současným - pokud je stejný, vypisuješ 2. a další jeho kategorii.
T-fon
Profil
Díky za reakce, výpis mám zjednodušeně cca takhle:
 while ($row = $stmt->fetch()) {
          echo $row->jmeno . '-' . $row->kategorie;
} 
Což vypíše Pavel-Kat1, Pavel-Kat2,... a já chci Pavel-Kat1, Kat2, ...
Takže řešení je uložit jméno do proměnné a to porovnat s novým a když shoda, tak se nevypíše, jestli to správně chápu.
Tomášeek
Profil
T-fon:
Takže řešení je uložit jméno do proměnné a to porovnat s novým a když shoda, tak se nevypíše, jestli to správně chápu.
Ano, řešení je uvedeno v Nadpis skupiny.

Pokud poslední jméno bude shodné s aktuálním, vypíšeš ', ' . $row->kategorie, výsledek pak bude Pavel-Kat1, Kat2.
T-fon
Profil
Paráda, s tou čárkou mě to nenapadlo. Tak je to ideální. Díky moc.
T-fon
Profil
Poprosil bych ještě o pomoc s tímto: chtěl bych výše uvedený výpis aplikovat na tento hotový script: jplist.com/layoutexamples/table-1.
Výpis do tabulky je zde řešen takto:
    class jPListHTML extends jPListServer{
            /**
            * get html for one item
            * @param {Object} $item
            * @return {string} html
            */
            private function getHTML($item){
                $html = "";
                $html .= "<div class='list-item box'>";    
                $html .= "    <div class='img left'>";
                $html .= "      <img src='" . $item['foto'] . "' alt='' title=''/>";
                $html .= "    </div>";

                $html .= "    <div class='block right'>";
                $html .= "        <p class='title'>" . $item['jmeno'] . "</p>";
                $html .= "        <p class='kategorie'>" . $item['kategorie'];
                $html .=       "</p>";
                $html .= "    </div>";
                $html .= "</div>";

                return $html;
            }
            /**
            * get the whole html
            * @param {string} $itemsHtml - items html
            * @return {string} html
            */
            private function getHTMLWrapper($itemsHtml){

                    $html = "";

                    $html .= "<div data-type='jplist-dataitem' data-count='" . $this->pagination->numberOfPages . "' class='box'>";
                    $html .= $itemsHtml;
                    $html .= "</div>";        

                    return $html;
            }

            /**
            * constructor
            */
            public function __construct(){

                    $html = "";

                    try{
            parent::__construct();

                            if(isset($this->statuses)){

                                    $items = $this->getData();

                                    if($items){
                                            foreach($items as $item){
                                                    $html .= $this->getHTML($item); 
                                            }                                            
                                    }

                ob_clean();

                                    //print html
                                    echo($this->getHTMLWrapper($html));
                            }

                            //close the database connection
                            $this->db = NULL;
                    }
                    catch(PDOException $ex){
                            print "Exception: " . $ex->getMessage();
                    }
            }
    }

    /**
    * start
    */
    new jPListHTML();

Je to už zjednodušeně upravené na můj dotaz do databáze:
SELECT jmeno, foto, kategorie.nazev AS kategorie FROM " . DB_TABLE . " JOIN uzivkat ON id_uzivatele=uzivatele.id JOIN kategorie ON id_kategorie=kategorie.id

V OOP jsem dost slabej, pokud to neni moc složité, poradili byste mi, aby výpis v tabulce nebyl:
Pavel-Kat1
Pavel-Kat2
... ,
jak je to teď, ale:
Pavel-Kat1, Kat2, ...
T-fon
Profil
Tohle bude asi dost složité, že? Nebo jsou neúplné informace ode mne?
Tomášeek
Profil
T-fon:
Takhle to nejde, protože pro každý vrácený záznam generuješ i celou omáčku okolo, včetně fotky atp.

Při prvním průchodu (1. kategorie k danému jménu) uzavřeš <p class="kategorie">, za něj vypíšeš další HTML. Při dalším průchodu už ale dovnitř tohoto stringu zapisovat nemůžeš, jak bys scriptu řekl, kam se má vrátit?

Mimochodem, špatně je i to, jakým způsobem to HTML generuješ. To patří do šablony, ne tam, kam jsi to umístil.

Nejjednodušší bude mít strukturu dat v následující formě:
jméno: Jan,
kategorie: array(
    kat1,
    kat2
)

Pak na místě, kde vypisuješ kategorii, uděláš implodem požadovaný řetězec. Případně by ti (možná?) mohl pomoci i GROUP_CONCAT přímo na úrovni SQL, který by tenhle string rovnou vrátil, pokud s jednotlivými položkami nepotřebuješ pracovat dále (třeba z nich udělat link do detailu kategorie).
T-fon
Profil
Zkusím, díky 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: