Dá se použít ->query() s SQL CASE a zároveň zachovat ActiveRow funkcionalita?
- warriotox
- Člen | 30
Mám dotaz na DB, kde si vytvářím extra pole RANGE a pomocí CASE ho
plním textem.
Vím, že to query můžu poslat natvrdo přes
->query($mujDotaz)
, ale právě jsem zjistil, že mi pak
v šabloně nelze volat na vztahy. Příklad, u rezervace mám klíč s ID
uživatele a v šabloně lze pak udělat
{$rezervace->klienti[jmeno]}
, ale jakmile to query vytvořím na
tvrdo, tak už to nefunguje.
$od = '2016-02-01';
$do = '2016-02-29';
SELECT *, CASE
WHEN `from` <= '$od' AND `to` >= '$do' THEN 'full'
WHEN `from` >= '$od' AND `to` < '$do' THEN 'fits'
WHEN `from` < '$od' AND `to` BETWEEN '$od' AND '$do' THEN 'past'
WHEN `from` BETWEEN '$od' AND '$do' AND `to` >= '$do' THEN 'extends'
END `range`
FROM reservations
HAVING `range` IS NOT NULL
Vím, že bych to query mohl doplnit o LEFT JOIN, ale líbila se mi ta
původní funkcionalita z ActiveRow..
Tudíž, dá se ten CASE napsat nějak podobně jako se píše například
->where()
či ->order()
? Nebo jak jinak
docílit toho abych mohl používat ActiveRow u tohodle dotazu?
- David Matějka
- Moderator | 6445
musis vsechny hodnoty (a to nejen to $od a $do, ale i full, fits atd.) pouzit parametry
->table('reservations')
->select('*, CASE
WHEN from <= ? AND to >= ? THEN ?
WHEN from >= ? AND to < ? THEN ?
....', $od, $do, 'full', $od, $do, 'fits', ...)
- warriotox
- Člen | 30
David Matějka napsal(a):
musis vsechny hodnoty (a to nejen to $od a $do, ale i full, fits atd.) pouzit parametry
Mockrát díky za rychlou odpověd. Doplnil jsem to, ale háže to chybu:
Nette\Database\DriverException #42000
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM `reservations`' at line 5.
Doplněný kód:
$db=$this->database->table('reservations')
->select('*, CASE
WHEN from <= ? AND to >= ? THEN ?
WHEN from >= ? AND to < ? THEN ?
WHEN from < ? AND to BETWEEN ? AND ? THEN ?
WHEN from BETWEEN ? AND ? AND to >= ? THEN ?'
,$od, $do, 'full'
,$od, $do, 'fits'
,$od, $od, $do, 'past'
,$od, $do, $do, 'extends');
Posalný query vypadá takhle:
SELECT *, CASE
WHEN `from` <= '2016-02-16' AND `to` >= '2016-02-23' THEN 'full'
WHEN `from` >= '2016-02-16' AND `to` < '2016-02-23' THEN 'fits'
WHEN `from` < '2016-02-16' AND `to` BETWEEN '2016-02-16' AND '2016-02-23' THEN 'past'
WHEN `from` BETWEEN '2016-02-16' AND '2016-02-23' AND `to` >= '2016-02-23' THEN 'extends'
FROM `reservations`
Není nutné tam nějak dopsat ještě to END RANGE a HAVING RANGE IS NOT NULL?
- David Matějka
- Moderator | 6445
ano, jen se mi to nechtelo psat cele. to end napis do selectu a having pomoci metody https://api.nette.org/…lection.html#…
- warriotox
- Člen | 30
David Matějka napsal(a):
ano, jen se mi to nechtelo psat cele. to end napis do selectu a having pomoci metody https://api.nette.org/…lection.html#…
Aha, já vždy čekám nějáke složité řešení, tak mě to ani nenapadlo
skusit. Mockrát děkuji.
Pro info, kompletní query:
$db=$this->database->table('reservations')
->select('*, CASE
WHEN from <= ? AND to >= ? THEN ?
WHEN from >= ? AND to < ? THEN ?
WHEN from < ? AND to BETWEEN ? AND ? THEN ?
WHEN from BETWEEN ? AND ? AND to >= ? THEN ? END `range`'
,$od, $do, 'full'
,$od, $do, 'fits'
,$od, $od, $do, 'past'
,$od, $do, $do, 'extends')->having('`range` IS NOT NULL');