J'essaie de trier une colonne de date en fonction du fait que l'indicateur payé est vrai ou faux. Si le drapeau payé est faux (non payé), je veux que le plus ancien apparaisse en premier. Si l'indicateur payé est vrai, je veux que le plus récent apparaisse en premier.

Requête actuelle:

SELECT due_date, date_paid, 
    IF(i.date_paid IS NULL, 0, 1) AS paid_flag 
FROM tc_vendorInvoices 
ORDER BY paid_flag, 
        CASE WHEN paid_flag = 0 THEN due_date END ASC, 
        CASE WHEN paid_flag = 0 THEN due_date END DESC 
LIMIT 0, 50

Cela ne trie que les drapeaux payés et la date d'échéance est ASC:

due_date   |    date_paid     |  paid_flag
2020-09-28          NULL             0
2020-09-29          NULL             0
2020-10-01          NULL             0
2020-09-14      2020-09-14           1 
2020-09-29      2020-09-29           1
2020-10-05      2020-10-05           1

Il doit trier comme ceci:

due_date   |    date_paid     |  paid_flag
2020-09-28          NULL              0
2020-09-29          NULL              0
2020-10-01          NULL              0
2020-10-05      2020-10-05            1
2020-09-29      2020-09-29            1
2020-09-14      2020-09-14            1
0
Judson Cooper 7 oct. 2020 à 18:45

2 réponses

Meilleure réponse

Une astuce avec le drapeau booléen paid_flag et la fonction to_seconds() le fera:

order by paid_flag,
         ((not paid_flag) - paid_flag) * to_seconds(due_date)

Lorsque paid_flag est 0, alors ((not paid_flag) - paid_flag) renvoie 1 donc le tri est croissant.
Lorsque paid_flag vaut 1, alors ((not paid_flag) - paid_flag) renvoie -1 donc le tri est effectué par -to_seconds(due_date) qui est décroissant.

Voir la démo.
Résultats:

> due_date   | date_paid  | paid_flag
> :----------| :--------- | --------:
> 2020-09-28 | null       |         0
> 2020-09-29 | null       |         0
> 2020-10-01 | null       |         0
> 2020-10-05 | 2020-10-05 |         1
> 2020-09-29 | 2020-09-29 |         1
> 2020-09-14 | 2020-09-14 |         1
0
forpas 7 oct. 2020 à 16:04

Nous ne pouvons pas déplacer ASC ou DESC dans une expression, cela fait partie de la clause ORDER BY. Donc, une construction comme celle-ci est correcte:

ORDER  
   BY fee
    , fi    DESC
    , fo    ASC

Nous pouvons utiliser des expressions pour renvoyer conditionnellement une valeur, puis trier sur cette expression. L'astuce consiste à renvoyer une valeur fixe pour les lignes que nous ne voulons pas être triées.

Quelque chose comme ça:

ORDER BY paid_flag
       , CASE paid_flag WHEN 0 THEN due_date ELSE NULL     END  ASC
       , CASE paid_flag WHEN 0 THEN NULL     ELSE due_date END  DESC 

Il existe d'autres approches; celui-ci se trouve juste imiter étroitement l'approche qu'il semble que l'original essayait.

0
spencer7593 7 oct. 2020 à 15:56