CASE in ORDER BY - mysql

I am using this ORDER BY clause in my MySQL query:
"ORDER BY FIELD(best_id.status, 'open', 'bekeken', 'verstuurd', 'binnen'), best_id.datum_leveren ASC
Works fine.
Now I would like to make an difference with sorting the rows, ASC combined with DESC. I have been trying to achieve this by change the clause to:
ORDER BY FIELD(best_id.status, 'open', 'bekeken', 'verstuurd', 'binnen'),
CASE WHEN best_id.status = 'binnen' THEN best_id.datum_leveren DESC, END
ELSE best_id.datum_leveren ASC END";
But I can't get it tow work. What is the right way for this or is it impossible to use an CASE in the ORDER BY clause?
Any help is much appreciated.

You can use
ORDER BY CASE
WHEN best_id.status = 'binnen'
THEN best_id.datum_leveren
ELSE NULL
END DESC,
CASE
WHEN best_id.status = 'binnen'
THEN NULL
ELSE best_id.datum_leveren
END ASC

Related

Symfony3-Doctrine : Order by Case When

I'm working on a Symfony 3.4 project.
I want to order a table by updated_at if exists (not null), by created_at if not.
In SQL, this works :
SELECT * FROM `contract`
ORDER BY
(CASE WHEN ISNULL(`updated_at`) THEN `created_at` ELSE `updated_at` END)
DESC
I tried a lot of things but I don't manage to make it work with Doctrine Query Builder.
First, I tried this (syntax error) :
$contracts = $em->createQuery(
'SELECT c
FROM AppBundle:Contract c
ORDER BY (CASE WHEN c.updatedAt = :update THEN c.createdAt ELSE c.updatedAt END) DESC')
->setParameter('update', NULL)
->getResult();
Then, I tried this according to this topic, but I have no result (no error) :
$contracts = $rp->createQueryBuilder('c')
->select('(CASE WHEN c.updatedAt != :update THEN 1 ELSE 0 END) AS HIDDEN orderDate')
->orderBy('orderDate', 'DESC')
->addOrderBy('c.createdAt', 'DESC')
->setParameter('update', NULL)
->getQuery()->getResult();
How can I sort my contracts by their updated date if they have been updated, or by their created date if they haven't been modified ?
If it helps, I use the DoctrineExtensions bundle for other queries, I saw IfNull and IfElse classes but I don't how to use them with my case.
After several attempts, I finally found the solution.
Use COALESCE : returns the first value not null in the list, so if A is null and B not null, then COALESCE(A,B) will return B.
$contracts = $rp->createQueryBuilder('c')
->select('c')
->addSelect('COALESCE(c.updatedAt,c.createdAt) AS HIDDEN orderDate')
->orderBy('orderDate', 'DESC')
->getQuery()->getResult();
No need to use the DoctrineExtensions bundle.

SQL order by string + integers

How can I ORDER BY a string which has ID at the end of the string?
For Example, I want to order these Strings by the numbers at the end (after RSPP):
RSPP891
RSPP896
RSPP897
RSPP898
RSPP899
RSPP900
RSPP901
RSPP902
RSPP903
RSPP904
RSPP730
RSPP731
RSPP1380
RSPP733
RSPP734
I read something about substringing so i tried this query instead, but without any success.
SELECT `RsppTags` FROM Table WHERE ConnectionID = 15202
ORDER BY
SUBSTR(RsppTags FROM 4 FOR LENGTH(RsppTags)-1),
CAST(SUBSTR(RsppTags FROM 1) AS UNSIGNED)
Is it possible to get this data ORDER BY ASC?
SELECT RsppTags FROM Table
WHERE ConnectionID = 15202
ORDER BY CAST(SUBSTR(RsppTags FROM 5) AS UNSIGNED)
By default MYSQL provide ASC ordering.
Try above query.
It will help you.
Try:
ORDER BY CAST(SUBSTR(RsppTags FROM 5) AS UNSIGNED) ASC
Sample SQL Fiddle showing the result
order by SUBSTR(RsppTags, 5) + 0
Try
SELECT `RsppTags` FROM Table WHERE ConnectionID = 15202
ORDER BY CAST(SUBSTR(RsppTags, 5) AS UNSIGNED) ASC;
SELECT `RsppTags`
FROM Table WHERE ConnectionID = 15202
ORDER BY
SUBSTR(RsppTags,1,4),
CAST(SUBSTR(RsppTags,5) AS UNSIGNED);

order by and case with mixed column datatype

we need to use order by with a case clause as the user may choose the type of order from the dropdown .. the situation seemed ok until a column with integer value wa also introduced.. it seems that for some reason, MYSQL is also assuming the integer column to be a string and ordering likewise ..
below is the order by clause
order by (case when p_SortBy = 'Default' then CONVERT(st.IncrementNo, unsigned)
WHEN p_SortBy ='Program'
THEN st.StudyProgram
WHEN p_SortBy = 'Student'
then st.Name
when p_SortBy = 'Mobile'
then st.Mobile
END) asc
the first case (Default) is for an integer value but it is sorting like so
105,106,107,108,109,11,110
any help appreciated..
You could use multiple CASE:
order by
case when p_SortBy = 'Default' then CONVERT(st.IncrementNo, unsigned) END,
case when p_SortBy = 'Program' then st.StudyProgram END,
case when p_SortBy = 'Student' then st.Name END,
case when p_SortBy = 'Mobile' then st.Mobile END

How to get the 1st transaction date then separate it to another column

I want to separate the 1st transaction date of every client to another column. Im not good at explaining. Hope the image below is enough to clarify my question..
I want to generate a result like in the picture. **I just edited this picture for the reference of the result that I want.
this my sqlfiddle ---> http://sqlfiddle.com/#!9/bebf5/1
I believe PN_NO represents client. We would need to perform ordering of rows based on PN_NO and Pay Date columns. It is needed to identify first transaction date. Please try below query.
SELECT
SCHED_NO,
PN_NO,
PAY_PRIN,
PAY_DATE,
CASE WHEN PN_NO_Rank=1 THEN PAY_DATE ELSE '' END AS BEGIN,
CASE WHEN PN_NO_Rank <>1 THEN PAY_DATE ELSE '' END AS CR
FROM
(
SELECT
SCHED_NO,
PN_NO,
PAY_PRIN,
PAY_DATE,
#PN_NO_Rank := IF(#current_PN_NO = PN_NO, #PN_NO_Rank + 1, 1) AS PN_NO_Rank,
#current_PN_NO := PN_NO
FROM PAY_SCHED
ORDER BY PN_NO, PAY_DATE ASC
) AS Temp
That should help:
SELECT SCHED_NO, PN_NO, PAY_PRIN, PAY_DATE,
CASE WHEN pay_date = (select min(pay_date) from pay_sched where pn_no=ps.pn_no) THEN pay_date ELSE NULL END as "BEGIN",
CASE WHEN pay_date = (select min(pay_date) from pay_sched where pn_no=ps.pn_no) THEN NULL ELSE pay_date END as "CR"
FROM PAY_SCHED ps order by pn_no, pay_date
http://sqlfiddle.com/#!9/bebf5/26/0

How to order by ASC, but to sort null at the last in mysql?

I have the below query in mysql, which sorts rows in ascending order of rm.meta_val. But in addition I want the null meta_val rows to be positioned at the last.
Could anyone help out?
SELECT rt.tax_id,ra.*,
FROM req_tax rt, req_aspects ra, req_meta rm
where ra.aspect_id = rt.req_aspects_id
and rt.tax_id=rm.req_tax_id
and rm.req_id = rt.req_id and rt.requests_id = 18
group by rt.tax_id
ORDER BY rm.meta_val asc;
Use IF in the ORDER BY clause:
ORDER BY
IF(rm.meta_val IS NULL, 1, 0),
rm.meta_val asc;
You can sort on a function result, so use an if to check whether the value is null, and if so return a very high value, otherwise return the value. Ideally, you would choose a value of the same type (number of bits, signed vs unsigned) based on the Max value being sorted plus one, as this avoids type promotion, but that may not be important to you. Switch the if returns if you want the nulls on the other end
SELECT rt.tax_id,ra.*,
FROM req_tax rt, req_aspects ra, req_meta rm
WHERE ra.aspect_id = rt.req_aspects_id
AND rt.tax_id=rm.req_tax_id
AND rm.req_id = rt.req_id
AND rt.requests_id = 18
GROUP BY rt.tax_id
ORDER BY if(rm.meta_val is NULL, 0xFFFFFFFF, rm.meta_val) asc;
try with case:
SELECT rt.tax_id,ra.*,
FROM req_tax rt, req_aspects ra, req_meta rm where ra.aspect_id = rt.req_aspects_id
and rt.tax_id=rm.req_tax_id and rm.req_id = rt.req_id and rt.requests_id = 18 group by rt.tax_id
order by case when rm.meta_val is null then 1 else 0 end, rm.meta_val
Try this query use ISNULL:-
order by ISNULL(rm.meta_val), rm.meta_val ASC
Your query like that :-
SELECT rt.tax_id,ra.*,
FROM req_tax rt, req_aspects ra, req_meta rm where ra.aspect_id = rt.req_aspects_id
and rt.tax_id=rm.req_tax_id
and rm.req_id = rt.req_id and rt.requests_id = 18 group by rt.tax_id order by ISNULL(rm.meta_val), rm.meta_val ASC;