Seřazení záznamů na základě podmínky
- ForestCZE
- Člen | 209
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 | 14
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 | 209
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. 2021 6:21)
- David Matějka
- Moderator | 6445
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
- ForestCZE
- Člen | 209
Snad nebude vadit, když znovu „otevřu“ vlákno. Týká se to stejného problému a nechci kvůli tomu zakládat nové vlákno.
Mám tabulku employees a v ní sloupce:
job, job_grade
job1, job_grade1
job2, job_grade2
Ten zaměstnanec dostane hodnotu jobu například ambulance, ale může tu hodnotu dostat do jednoho ze tří sloupců (job, job1, job2), podle jeho volného slotu. Následně dostane číslo pozice od 0 do 7 do příslušného sloupce podle jobu. Takže pokud je to např. job1, pak dostane číslo pozice do job_grade1 a nikam jinam.
Rád bych seřadil job_grade, job_grade1 a job_grade2 od nejvyšší pozice po nejnižší, tedy sestupně. Problém ale je, že je to závisle na tom jobu. Tudíž když udělám:
order('job_grade DESC, job_grade1 DESC a job_grade2 DESC')
tak zaměstnanec s job_grade: 6 bude výše než zaměstnanec s job_grade1: 7, neboť se job_grade řadí dříve. Lze to nějak udělat, aby se to řadilo nezávisle?
Zkusil jsem:
... ->order('CASE WHEN job = ? THEN job_grade DESC END, CASE WHEN job1 = ? THEN job_grade1 DESC END, CASE WHEN job2 = ? THEN job_grade2 DESC END', self::JOB, self::JOB, self::JOB);
což nelze, jelikož, jak už tady bylo zmíněno, DESC nelze z CASE „vrátit“. Jak na to tedy? Díky moc předem.
Editoval ForestCZE (17. 6. 2021 4:07)
- ForestCZE
- Člen | 209
David Matějka napsal(a):
ten směr řazení (DESC) dej až za CASE (resp za END)
@DavidMatějka to už jsem také zkoušel. QUERY v laděnce:
ORDER BY CASE WHEN `job` = 'ambulance' THEN `job_grade` END DESC, CASE WHEN `job1` = 'ambulance' THEN `job_grade1` END
DESC, CASE WHEN `job2` = 'ambulance' THEN `job_grade2` END DESC
Šablona – řadí se to špatně – boss by měl být nahoře