Jak správně napsat dotaz s JOIN přes Nette

Laxren
Backer | 23
+
0
-

Mám 2 tabulky category a parent_category (kvůli tomu, že 1 kategorie může mít více rodičů).
Potřebuji vypsat všechny kategorie.

DROP TABLE IF EXISTS `category`;
CREATE TABLE `category` (
  `category_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) COLLATE utf8_czech_ci DEFAULT NULL,
  `order_no` int(11) DEFAULT NULL,
  `hidden` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`category_id`),
  UNIQUE KEY `url` (`url`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;


DROP TABLE IF EXISTS `parent_category`;
CREATE TABLE `parent_category` (
  `parent_category_id` int(11) NOT NULL AUTO_INCREMENT,
  `category_id` int(11) NOT NULL,
  `parent_id` int(11) NOT NULL,
  PRIMARY KEY (`parent_category_id`),
  KEY `category_id` (`category_id`),
  KEY `parent_id` (`parent_id`),
  CONSTRAINT `parent_category_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`),
  CONSTRAINT `parent_category_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `category` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

S tímto dotazem se to vykoná, tak jak má:

$categories = $this->database->query('
    SELECT category.category_id, category.url, category.title, category.order_no,
    category.hidden, parent_category.parent_id
    FROM category
    LEFT JOIN parent_category ON category.category_id = parent_category.category_id
');
return $categories->fetchAll(); // Vrátí 27 výsledků (to je dobře)

Jak by jste to napsali přes Nette?
Zkoušel jsem toto:

$categories = $this->database->table('category');
$categories->select('category.category_id');
$categories->select('category.url');
$categories->select('category.title');
$categories->select('category.order_no');
$categories->select('category.hidden');
$categories->select(':parent_category.parent_id');

return $categories->fetchAll(); // Vrátí 16 výsledků (to je špatně)

U tohoto, když je duplicitní category_id, tak to nějak spojí a vyhodí jen jednu kategorii, místo toho, aby jich vrátilo tolik kolik má s jiným parent_id.
Divný je, že oba způsoby vygenerují úplně stejný dotaz, ale výsledek je jiný.

Ale když se dá alias ke category_id, tak to pak už vrátí stejný, správný, počet výsledků jako ten první příklad.

$categories = $this->database->table('category');
$categories->select('category.category_id AS categ_id'); // AS
$categories->select('category.url');
$categories->select('category.title');
$categories->select('category.order_no');
$categories->select('category.hidden');
$categories->select(':parent_category.parent_id');

return $categories->fetchAll(); // Vrátí 27 výsledků (to je dobře)

Možná je logické, že výsledky se stejným category_id spojí, ale jak ten dotaz napsat přes Nette, aby se nemusel používat alias a vypsal stejný počet výsledků jako první příklad?

David Grudl
Nette Core | 8111
+
0
-

Tohle funguje a je to taky „přes Nette“, proč si komplikovat život?

$categories = $this->database->query('
    SELECT category.category_id, category.url, category.title, category.order_no,
    category.hidden, parent_category.parent_id
    FROM category
    LEFT JOIN parent_category ON category.category_id = parent_category.category_id
');
return $categories->fetchAll();
David Matějka
Moderator | 6445
+
0
-

jaky sql dotaz to vygeneruje?

zkus neco jako

$categories->select(':parent_category(category_id).parent_id');

@DavidGrudl pak prijdes o vyhody, ktere poskytuje ndb explorer

Laxren
Backer | 23
+
0
-

Děkuji za odpovědi.

@DavidGrudl Určitě by to bylo nejjednodušší řešení, ale jen by mě zajímalo, jak by se to napsalo přes Database Explorer

@DavidMatějka
Vygeneruje to:

SELECT `category`.`category_id`, `category`.`url`, `category`.`title`, `category`.`order_no`,
`category`.`hidden`, `parent_category`.`parent_id`
FROM `category`
LEFT JOIN `parent_category` ON `category`.`category_id` = `parent_category`.`category_id`

S tímto:

$categories->select(':parent_category(category_id).parent_id');

Je pořád stejný výsledek.

Editoval Laxren (1. 10. 2018 12:05)

David Matějka
Moderator | 6445
+
+4
-

jo uz vim, kde je problem. ndb explorere groupuje result dle primary key te zakladni tabulky – v tvem pripade dle category.category_id. Resenim bude query nepokladat od tabulky category, ale od parent_category. tedy

$this->database->table('parent_category');

a upravit vsechny ty selecty apod.

Laxren
Backer | 23
+
0
-

Děkuji.

Přepsal jsem to na tohle:

$categories = $this->database->table('parent_category');
$categories->select('category.category_id');
$categories->select('category.url');
$categories->select('category.title');
$categories->select('category.order_no');
$categories->select('category.hidden');
$categories->select('parent_category.parent_id');

return $categories->fetchAll();

Funguje to, jen jsem musel přidat do tabulky parent_category i nejvyšší kategorie, který nemají žádného rodiče, ty tam předtím nebyly potřeba.

Ještě jednou díky.

Editoval Laxren (1. 10. 2018 15:10)