Я хочу оценить, выполняются ли определенные условия, а затем возвращать определенный текст. Я использую синтаксис CASE, но я не совсем уверен, что это самый практичный способ сделать это. Также потому, что определенные условия должны соответствовать дополнительным условиям (инструкция WHEN, которая возвращает «Задержка»). Несмотря на то, что это выглядит беспорядочно, он работает, за исключением последних критериев в заявлении «Задержка».Несколько условий в операторе CASE
Это мое текущее заявление СЛУЧАЙ:
CASE
WHEN
(stf.status_id IN ('38','14','13','12','16','18') AND stf.date >= (p.fecha_prevista_entrega + INTERVAL '30 minutes'))
OR (stf.status_id IN ('38','14','13','12','16','18') AND stf.date < (os.rider_accepted + INTERVAL '5 minutes'))
THEN 'Not Paid - Cancelled'
WHEN
(stf.status_id IN ('38','14','13','12','16','18') AND stf.date <= (p.fecha_prevista_entrega + INTERVAL '30 minutes'))
AND (stf.status_id IN ('38','14','13','12','16','18') AND stf.date >= p.fecha_entrega_repartidor)
THEN 'Paid - Cancelled'
WHEN
(u.first_name ILIKE '%LKF%' AND ((EXTRACT(HOUR FROM os.food_delivered - p.fecha_prevista_entrega)*60+EXTRACT(MINUTE FROM os.food_delivered - p.fecha_prevista_entrega)+EXTRACT(SECOND FROM os.food_delivered - p.fecha_prevista_entrega)/60) > '15'))
OR (u.first_name NOT ILIKE '%LKF%' AND ((EXTRACT(HOUR FROM os.food_delivered - p.fecha_prevista_entrega)*60+EXTRACT(MINUTE FROM os.food_delivered - p.fecha_prevista_entrega)+EXTRACT(SECOND FROM os.food_delivered - p.fecha_prevista_entrega)/60) > '30'))
AND (
((od.preorder = '0' AND od.order_comment ILIKE '%' || u.first_name || '%') AND (EXTRACT(HOUR FROM os.rider_assigned - od.date)*60+EXTRACT(MINUTE FROM os.rider_assigned - od.date)+EXTRACT(SECOND FROM os.rider_assigned - od.date)/60) < '15')
OR
((od.preorder = '0' AND od.order_comment NOT ILIKE '%' || u.first_name || '%') AND (EXTRACT(HOUR FROM os.rider_assigned - od.date)*60+EXTRACT(MINUTE FROM os.rider_assigned - od.date)+EXTRACT(SECOND FROM os.rider_assigned - od.date)/60) < '20')
OR
(od.preorder = '1' AND (EXTRACT(HOUR FROM p.fecha_prevista_entrega - os.rider_assigned)*60+EXTRACT(MINUTE FROM p.fecha_prevista_entrega - os.rider_assigned)+EXTRACT(SECOND FROM p.fecha_prevista_entrega - os.rider_assigned)/60) > '30')
OR
((EXTRACT(HOUR FROM os.food_delivered - p.fecha_prevista_entrega)*60+EXTRACT(MINUTE FROM os.food_delivered - p.fecha_prevista_entrega)+EXTRACT(SECOND FROM os.food_delivered - p.fecha_prevista_entrega)/60) > '15')
OR
((os.rider_at_restaurant >= (p.fecha_entrega_repartidor + INTERVAL '3 minutes')) AND ((EXTRACT(HOUR FROM os.food_picked_up - p.fecha_entrega_repartidor)*60+EXTRACT(MINUTE FROM os.food_picked_up - p.fecha_entrega_repartidor)+EXTRACT(SECOND FROM os.food_picked_up - p.fecha_entrega_repartidor)/60) < '15'))
)
THEN 'Delay'
ELSE 'None' END AS payment_adj
Эта часть заявления не работает:
OR
((os.rider_at_restaurant >= (p.fecha_entrega_repartidor + INTERVAL '3 minutes')) AND ((EXTRACT(HOUR FROM os.food_picked_up - p.fecha_entrega_repartidor)*60+EXTRACT(MINUTE FROM os.food_picked_up - p.fecha_entrega_repartidor)+EXTRACT(SECOND FROM os.food_picked_up - p.fecha_entrega_repartidor)/60) < '15'))
Я перепроверить несколько результатов, которые показывают «Пауза», но не показывать потому что они не соответствуют этому условию.
Вот полный запрос
WITH order_steps AS
(
SELECT pedido_id,
MAX(CASE WHEN situacion = 0 THEN created_at END) AS rider_assigned,
MAX(CASE WHEN situacion = 1 THEN created_at END) AS rider_viewed,
MAX(CASE WHEN situacion = 2 THEN created_at END) AS rider_accepted,
MAX(CASE WHEN situacion = 3 THEN created_at END) AS rider_at_restaurant,
MAX(CASE WHEN situacion = 4 THEN created_at END) AS food_picked_up,
MAX(CASE WHEN situacion = 5 THEN created_at END) AS rider_at_customer,
MAX(CASE WHEN situacion = 6 THEN created_at END) AS food_delivered,
MAX(CASE WHEN situacion = 10 THEN created_at END) AS unknown_status
FROM dwh.tracking_motero t
GROUP BY 1
ORDER BY 1,2
),
assigned_riders AS (
WITH rider_assignments AS (
SELECT mp.pedido_id, mp.motero_id, mp.created_at, ROW_NUMBER() OVER (PARTITION BY mp.pedido_id ORDER BY mp.created_at DESC) AS last_assignments
FROM dwh.motero_pedido mp
)
SELECT pedido_id, motero_id FROM rider_assignments
WHERE last_assignments = 1
)
SELECT
CASE
WHEN
(stf.status_id IN ('38','14','13','12','16','18') AND stf.date >= (p.fecha_prevista_entrega + INTERVAL '30 minutes'))
OR (stf.status_id IN ('38','14','13','12','16','18') AND stf.date < (os.rider_accepted + INTERVAL '5 minutes'))
THEN 'Not Paid - Cancelled'
WHEN
(stf.status_id IN ('38','14','13','12','16','18') AND stf.date <= (p.fecha_prevista_entrega + INTERVAL '30 minutes'))
AND (stf.status_id IN ('38','14','13','12','16','18') AND stf.date >= p.fecha_entrega_repartidor)
THEN 'Paid - Cancelled'
WHEN
(u.first_name ILIKE '%LKF%' AND ((EXTRACT(HOUR FROM os.food_delivered - p.fecha_prevista_entrega)*60+EXTRACT(MINUTE FROM os.food_delivered - p.fecha_prevista_entrega)+EXTRACT(SECOND FROM os.food_delivered - p.fecha_prevista_entrega)/60) > '15'))
OR (u.first_name NOT ILIKE '%LKF%' AND ((EXTRACT(HOUR FROM os.food_delivered - p.fecha_prevista_entrega)*60+EXTRACT(MINUTE FROM os.food_delivered - p.fecha_prevista_entrega)+EXTRACT(SECOND FROM os.food_delivered - p.fecha_prevista_entrega)/60) > '30'))
AND (
((od.preorder = '0' AND od.order_comment ILIKE '%' || u.first_name || '%') AND (EXTRACT(HOUR FROM os.rider_assigned - od.date)*60+EXTRACT(MINUTE FROM os.rider_assigned - od.date)+EXTRACT(SECOND FROM os.rider_assigned - od.date)/60) < '15')
OR
((od.preorder = '0' AND od.order_comment NOT ILIKE '%' || u.first_name || '%') AND (EXTRACT(HOUR FROM os.rider_assigned - od.date)*60+EXTRACT(MINUTE FROM os.rider_assigned - od.date)+EXTRACT(SECOND FROM os.rider_assigned - od.date)/60) < '20')
OR
(od.preorder = '1' AND (EXTRACT(HOUR FROM p.fecha_prevista_entrega - os.rider_assigned)*60+EXTRACT(MINUTE FROM p.fecha_prevista_entrega - os.rider_assigned)+EXTRACT(SECOND FROM p.fecha_prevista_entrega - os.rider_assigned)/60) > '30')
OR
((EXTRACT(HOUR FROM os.food_delivered - p.fecha_prevista_entrega)*60+EXTRACT(MINUTE FROM os.food_delivered - p.fecha_prevista_entrega)+EXTRACT(SECOND FROM os.food_delivered - p.fecha_prevista_entrega)/60) > '15')
OR
((os.rider_at_restaurant >= (p.fecha_entrega_repartidor + INTERVAL '3 minutes')) AND ((EXTRACT(HOUR FROM os.food_picked_up - p.fecha_entrega_repartidor)*60+EXTRACT(MINUTE FROM os.food_picked_up - p.fecha_entrega_repartidor)+EXTRACT(SECOND FROM os.food_picked_up - p.fecha_entrega_repartidor)/60) < '15'))
)
THEN 'Delay'
ELSE 'None' END AS payment_adj,
p.id AS urban_ninja_id,
o.order_fp_code AS order_code,
p.total AS order_amount,
p.paymenttype_name,
u.first_name AS rider_code,
p.direccion AS delivery_address,
p.fecha_entrega_repartidor AS expected_pick_up_time,
p.fecha_prevista_entrega AS expected_delivery_time,
od.date AS order_creation_date,
os.rider_assigned,
os.rider_viewed,
os.rider_accepted,
os.rider_at_restaurant,
os.food_picked_up,
os.rider_at_customer,
os.food_delivered,
os.unknown_status,
st.id AS status_id,
st.code AS status_code,
st.title AS status,
ve.title AS vendor,
EXTRACT(HOUR FROM os.rider_assigned-od.date)*60+EXTRACT (MINUTE FROM os.rider_assigned-od.date)+EXTRACT (SECOND FROM os.rider_assigned-od.date)/60 AS dispatching_time,
EXTRACT(HOUR FROM os.rider_viewed-os.rider_assigned)*60+EXTRACT (MINUTE FROM os.rider_viewed-os.rider_assigned)+EXTRACT (SECOND FROM os.rider_viewed-os.rider_assigned)/60 AS rider_reaction_time,
EXTRACT(HOUR FROM os.rider_accepted-os.rider_viewed)*60+EXTRACT (MINUTE FROM os.rider_accepted-os.rider_viewed)+EXTRACT (SECOND FROM os.rider_accepted-os.rider_viewed)/60 AS rider_acceptance_time,
EXTRACT(HOUR FROM os.rider_at_restaurant-os.rider_accepted)*60+EXTRACT (MINUTE FROM os.rider_at_restaurant-os.rider_accepted)+EXTRACT (SECOND FROM os.rider_at_restaurant-os.rider_accepted)/60 AS rider_driving_to_restaurant_time,
EXTRACT(HOUR FROM os.food_picked_up-os.rider_at_restaurant)*60+EXTRACT (MINUTE FROM os.food_picked_up-os.rider_at_restaurant)+EXTRACT (SECOND FROM os.food_picked_up-os.rider_at_restaurant)/60 AS rider_in_restaurant_time,
EXTRACT(HOUR FROM os.rider_at_customer-os.food_picked_up)*60+EXTRACT (MINUTE FROM os.rider_at_customer-os.food_picked_up)+EXTRACT (SECOND FROM os.rider_at_customer-os.food_picked_up)/60 AS rider_driving_to_customer_time,
EXTRACT(HOUR FROM os.food_delivered-os.rider_at_customer)*60+EXTRACT (MINUTE FROM os.food_delivered-os.rider_at_customer)+EXTRACT (SECOND FROM os.food_delivered-os.rider_at_customer)/60 AS rider_at_customer_time,
EXTRACT (HOUR FROM os.food_delivered-od.date)*60 + EXTRACT (MINUTE FROM os.food_delivered-od.date) + EXTRACT (SECOND FROM os.food_delivered-od.date)/60 AS delivery_time,
od.order_comment,
od.preorder
FROM dwh.pedido p
LEFT JOIN dwh.order_fp o ON p.id = o.pedido_id
LEFT JOIN order_steps os ON os.pedido_id = p.id
LEFT JOIN assigned_riders r ON r.pedido_id = p.id
LEFT JOIN dwh.moteros m ON m.id = r.motero_id
LEFT JOIN dwh.sf_guard_user u ON u.id = m.sf_guard_user_id
INNER JOIN dwh."Orders" od ON od.id = o.order_fp_id
INNER JOIN dwh."Status" st ON st.id = od.status_id
INNER JOIN dwh."Statusflows" stf ON stf.order_id = od.id
INNER JOIN dwh."Vendors" ve ON od.vendor_id = ve.id
WHERE u.first_name NOT IN ('TEST RIDER','Jan')
and os.rider_accepted between (current_date-30) and (current_date-1)
GROUP BY p.id, stf.status_id, stf.date, os.rider_accepted, u.first_name, os.food_delivered, od.preorder, od.order_comment, os.rider_assigned, od.date, os.food_picked_up, os.rider_at_restaurant, o.order_fp_code, os.rider_viewed, os.rider_at_customer, os.unknown_status, st.id, ve.title
LIMIT 100;
Что значит не работает? Какая ошибка? Для этого скрипта установите флажки в скобках. Кроме того, если инструкции 'CASE/WHEN' становятся сложными, рассмотрите возможность использования запросов UNION. Если это не производительность, это может помочь, по крайней мере, для удобства чтения и обслуживания. – Parfait
@Parfait Извините, я должен настроить то, что я сказал раньше. Что происходит в части «Задержка», оно должно проверять начальное условие (часть u.first_name) и затем проверять, соответствует ли оно любому из условий, указанных ниже (после части AND). Я думаю, что я ошибся в своем первоначальном описании вопроса, кажется, что запрос не учитывает часть AND, а не только конечный критерий, упомянутый в моем первоначальном вопросе. – Mischa
@Патрик извиняется, полный запрос добавлен сейчас. – Mischa