Seřazení záznamů na základě podmínky

ForestCZE
Člen | 185
+
0
-

Ahoj, snažím se seřadit záznamy dle podmínky následovně:

return $this->database->getTournaments()->where('removed', false)->order('active DESC, (CASE WHEN active = ? THEN start_date, start_time ELSE start_date DESC, start_time DESC END)', true);

Vyhodí to error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' `start_time ELSE start_date DESC, start_time DESC END) LIMIT 20' at line 1`

Je možné to nějak takto podobně použít?

pux
Člen | 15
+
+1
-

CASE neumožňuje návrat více výrazů, viz. citace ze StackOveflow:

CASE is an expression – it returns a single scalar value (per row). It can't return a complex part of the parse tree of something else, like an ORDER BY clause of a SELECT statement.

Napadá mě zkusit ORDER BY část rozepsat:

ORDER BY active DESC,
CASE WHEN active = true THEN start_date END,
CASE WHEN active = true THEN start_time END,
CASE WHEN active = false THEN start_date DESC END,
CASE WHEN active = false THEN start_time DESC END

Výsledek by tedy byl:

return $this->database->getTournaments()->where('removed', false)->order('ORDER BY active DESC, CASE WHEN active = ? THEN start_date END, CASE WHEN active = ? THEN start_time END, CASE WHEN active = ? THEN start_date DESC END, CASE WHEN active = ? THEN start_time DESC END', true, true, false, false);
ForestCZE
Člen | 185
+
0
-

pux napsal(a):

CASE neumožňuje návrat více výrazů, viz. citace ze StackOveflow:

CASE is an expression – it returns a single scalar value (per row). It can't return a complex part of the parse tree of something else, like an ORDER BY clause of a SELECT statement.

Napadá mě zkusit ORDER BY část rozepsat:

ORDER BY active DESC,
CASE WHEN active = true THEN start_date END,
CASE WHEN active = true THEN start_time END,
CASE WHEN active = false THEN start_date DESC END,
CASE WHEN active = false THEN start_time DESC END

Výsledek by tedy byl:

return $this->database->getTournaments()->where('removed', false)->order('ORDER BY active DESC, CASE WHEN active = ? THEN start_date END, CASE WHEN active = ? THEN start_time END, CASE WHEN active = ? THEN start_date DESC END, CASE WHEN active = ? THEN start_time DESC END', true, true, false, false);

Wow, moc děkuju. Vypadá to logicky, i když je to delší. Spíše jsem se začínal pomalu smiřovat s tím, že to nepůjde.

Musel jsem tedy odstranit ORDER BY, které tam bylo navíc kvůli té funkci order(), nicméně je prý stále chyba v syntaxi:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DESC END, CASE WHEN `active = 0 THEN start_time DESC END LIMIT 20' at line 1`

Tracy vyhodí dotaz v podobě:

SELECT `id`, `logo`, `name`, `ongoing`, `start_date`, `start_time`, `mode_id`, `current_teams`,
`max_teams`, `active`
FROM `tournaments`
WHERE (`removed` = ?)
ORDER BY `active` DESC, CASE WHEN `active` = ? THEN `start_date` END, CASE WHEN `active` = ? THEN
`start_time` END, CASE WHEN `active` = ? THEN `start_date` DESC END, CASE WHEN `active` = ? THEN
`start_time` DESC END
LIMIT 20
return $this->database->getTournaments()->where('removed', false)->order('active DESC, CASE WHEN active = ? THEN start_date END, CASE WHEN active = ? THEN start_time END, CASE WHEN active = ? THEN start_date DESC END, CASE WHEN active = ? THEN start_time DESC END', true, true, false, false);

Vypadá to, že ta funkce order() nechce vzít argumenty. Proč?
EDIT: Koukám, že ani where() nevezme argument, přitom normálně ano…

Editoval ForestCZE (6. 4. 6:21)

David Matějka
Moderator | 6407
+
+1
-

ani desc nemůžeš z case „vrátit“, potřebuješ nejdříve neseřadit ty neaktivní a až v dalším orderu je seřadit sestupně:

ORDER BY
	active DESC,
	CASE WHEN active = 0 THEN NULL ELSE start_date END,
	CASE WHEN active = 0 THEN NULL ELSE start_time END,
	start_date DESC,
	start_time DESC