Problém s dotazem při spojování tabulek. Jak funguje JOIN?

- iskejp
 - Člen | 41
 
Zdravím,
potřebuji poradit s chybou v dotazu do DB.
Dotaz v modelu:
SELECT `article_has_file`.`file_id`, `file`.`id`
FROM `article_has_file`
LEFT JOIN `file` ON `article_has_file`.`file_id` = `file`.``
WHERE (`article_has_file`.`article_id` = ?)
Vypíše chybu: SQLSTATE[42S22]: Column not found: 1054 Unknown column ‚file.‘ in ‚on clause‘
Není mi jasné proč se nedoplní file.id v části ON. Jak vlastně funguje sestavení JOIN dotazu?
Díky moc. Pokud to není jasné, rád upřesním.

- SendiMyrkr
 - Člen | 30
 
na koncí tý řádky s ON máš „file.``“
takže se snažíš vybrat jakoby z tabulky file sloupec bezejména…
edit.
sorry nedočetl jsem to celý… máš na tom sloupci id primary key?
Editoval SendiMyrkr (22. 10. 2012 1:29)

- iskejp
 - Člen | 41
 
To Enumg: PHP v modelu je následující.
public function getFileUse ($articleId) {
    return $this->select('article_has_file.file_id, file.id')->where('article_has_file.article_id = ?', $articleId);
    }
To SendiMyrkr: Ano, id je PRIMARY KEY. Ještě pro jistotu dodávám, že mám aktuální verzi Nette 2.0.6.

- iskejp
 - Člen | 41
 
Tak to jsem rád, že si to nemyslím sám :o).
Jinak model vypadá takto:
class AddFiles extends Selection {
public function __construct(Connection $connection)
    {
        parent::__construct('article_has_file', $connection);
    }
public function insertFile ($articleId, $fileId, $userId) {
        return $this->insert(array(
           'article_id' => $articleId,
           'article_user_id' => 1,
           'file_id' => $fileId,
           'file_user_id' => $userId
        ));
    }
public function getFileUse ($articleId) {
    return select('article_has_file.file_id, file.id')->where('article_has_file.article_id = ?', $articleId);
    }
}
Pokud tam je něco špatně, rád se dozvím jak na to správně. Vycházel jsem z tutorialu.
A co se týče toho dotazu. Mám za to, že article_has_file.file_id vytáhne ID z N:N tabulky a spojí jej s file.id pro načtení dat o souboru.
Díky za pomoc.

- iskejp
 - Člen | 41
 
Opět zdravím,
bohužel mi stále JOIN nefunguje. Nastudoval jsem změny modelů (jsou hezké), instaloval nejnovější verzi Nette, ale stále nic. Tentokrát mi hází chybu No reference found for $articleFile->articlefile.
Dotaz ve třídě ArticleFileRepository:
 public function findFileUse ($articleId)
        {
            return $this->findWhere('articlefile.file_id='.$articleId);
        }
Repository navazující na Quickstart:
 public function findWhere($string)
        {
            return $this->getTable()->where($string);
        }
Chybu v laděnce hlásí až render v komponentě při volání count:
public function render(){
            $this->template->setFile(__DIR__.'/FileManage.latte');
           $this->template->file = $this->fileManage;
           $this->template->countFiles = count($this->fileManage);
           $this->template->render();
        }
Díky za pomoc.

- iskejp
 - Člen | 41
 
Tak nakonec to nefunguje. Jelikož jsem změnou parametru WHERE zrušil JOIN. Dopracoval jsem se k hlášce:
PDOException #42S22
SQLSTATE[42S22]: Column not found: 1054 Unknown column ‚file.article_id‘ in
‚where clause‘
Dotaz do WHERE:
findWhere('file.article_id='.$articleId)
S tím, že výsledné SQL je:
`SELECT `articleFile`.*
FROM `articleFile`
INNER JOIN `file` ON `articleFile`.`file_id` = `file`.``
WHERE (`file`.`article_id`=13)`
Kde je chyba je mi jasné. V tabulce file žádný sloupec
article_id neexituje. Jenže pak nevím jak tedy vytvořit JOIN
2 tabulek. Navíc je podezřelé, že je prázdný řetězec
file.``.
Můžete někdo poradit jak to vlastně funguje? Díky.
Editoval iskejp (12. 11. 2012 22:23)

- iskejp
 - Člen | 41
 
Zdravím,
při pokusu o nalezení řešení problému se spojováním tabulek jsem vytvořil vlákno, které se postupem doby opět vyvinulo ve stejný problém. Myslím, že patří spíše sem.
https://forum.nette.org/…g-conversion#… (Na odkazu je výpis kódu a struktury DB.)
Při pokusech o nalezení řešení jsem přesunul dotaz do DB z ArticleFileRepository do FileRepository a změnil kód dotazu na tento:
return $this->findJoin('13:articlefile:file_id');
Vysvětlivka: 13 je pokusné ID článku ke kterému se mají připojit soubory. Dle mého pozorování má být na tomto místě $key a nikoli $table jak je uvedeno v návodu výše od enumaga.
Laděnka pak hlásí „Array to string conversion“ a toto:
 ...\libs\Nette\Database\Table\SqlBuilder.php:323 source ▼  Nette\Database\Drivers\MySqlDriver-> delimite (arguments ▼)
$name
array(2) ▼ [
   0 => "id" (2)
   1 => "user_id" (7)
]
Pokud se nepletu, je toto spíše funkční a správná cesta, které ovšem někde selhává. Bohužel nemohu vůbec přijít kde. Můžete opět poradit, či naťuknout?
Díky.

- iskejp
 - Člen | 41
 
Zkusil jsem nasadit vývojovou verzi, ale je tam toho asi poměrně dost jiného a nepodařilo se mi to správně odladit :o(.
FindJoin vypadá takto:
public function findJoin($select/*, $where*/)
        {
            return $this->getTable()->select($select)/*->where($where)*/;
        }
Zkoušel jsem jej bez části where, jelikož mi přišlo, že JOIN v Nette funguje buď přes WHERE, nebo přes SELECT, ale nikoli přes oboje.
EDIT: Nakonec jsem to vyřešil přes query.
Editoval iskejp (24. 12. 2012 16:45)