Можно ли улучшить функцию CASE? - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь получить сообщение из базы данных, чтобы узнать, был ли заказ доставлен вовремя или нет. Я повторяю кусок кода несколько раз внутри функции «CASE».

Можно ли его улучшить / оптимизировать?

SELECT (CASE 
          WHEN ROUND((UNIX_TIMESTAMP(orders.delivered_at) - UNIX_TIMESTAMP(DATE_ADD(orders.created_at, INTERVAL (order.time) + 25) MINUTE)))/60) > 0 
            THEN CONCAT('Order delivered with ', ROUND((UNIX_TIMESTAMP(orders.delivered_at) - UNIX_TIMESTAMP(DATE_ADD(orders.created_at, INTERVAL (order.time) + 25) MINUTE)))/60), ' minutes delay.') 
          WHEN ROUND((UNIX_TIMESTAMP(orders.delivered_at) - UNIX_TIMESTAMP(DATE_ADD(orders.created_at, INTERVAL (order.time) + 25) MINUTE)))/60) < 0 
            THEN CONCAT('Order delivered ', ABS(ROUND((UNIX_TIMESTAMP(orders.delivered_at) - UNIX_TIMESTAMP(DATE_ADD(orders.created_at, INTERVAL (order.time) + 25) MINUTE)))/60)), ' minutes faster.')
          ELSE 'Order delivered on time.' 
        END ) as message
FROM orders;

Вот схема таблицы:

+----------+---------------------+----------------------+----------------+
| order_id | created_at          | delivered_at         | time (minutes) |
+----------+---------------------+----------------------+----------------+
| 1        | 2020-04-13 10:10:00 | 2020-04-13 12:30:00  | 20             |
+----------+---------------------+----------------------+----------------+
| 2        | 2020-04-13 14:20:00 | 2020-04-13 14:50:00  | 30             |
+----------+---------------------+----------------------+----------------+

Для первого порядка результат должно быть «Заказ задерживается на 95 минут». , а для второго «Заказ доставляется на 25 минут быстрее.» .

Разница во времени между выполнением заказа был фактически доставлен, и когда он должен был быть доставлен, вычисляется следующим образом: orders.delivered_at - (orders.created_at + time + 25)

Запрос возвращает правильные данные, но можно ли их УЛУЧШИТЬ? Можно ли выполнить sth, чтобы не повторять дублированный код «ROUND ((UNIX_TIMESTAMP (....»)?

1 Ответ

0 голосов
/ 13 апреля 2020

Получите разницу в минутах с псевдонимом из подзапроса и используйте ее следующим образом:

SELECT
  CASE 
    WHEN o.diff > 0 THEN CONCAT('Order delivered with ', o.diff, ' minutes delay.') 
    WHEN o.diff < 0 THEN CONCAT('Order delivered ', ABS(o.diff), ' minutes faster.')
    ELSE 'Order delivered on time.' 
  END as message
FROM (
  SELECT 
    ROUND((UNIX_TIMESTAMP(orders.delivered_at) - UNIX_TIMESTAMP(DATE_ADD(orders.created_at, INTERVAL (orders.time) + 25 MINUTE)))/60)   as diff
  FROM orders
) as o

См. Демонстрационную версию . Результаты:

| message                                |
| -------------------------------------- |
| Order delivered with 95 minutes delay. |
| Order delivered 25 minutes faster.     |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...