MySQL: Количество (*) NULL -> 0 с правым объединением - PullRequest
0 голосов
/ 23 марта 2020

Я близок к завершению сложной проблемы LeetCode. Идея состоит в том, чтобы найти процент отмены (процент) для диапазона дат, учитывая, что ни водитель, ни клиент не были забанены в службе обмена поездками.

Проблема, с которой я сталкиваюсь, заключается в том, что 2 октября отмены не было; используя внутреннее соединение, эта дата опускается. Используя правое соединение, значение возвращается как NULL. Мне нужно, чтобы это значение NULL было сопоставлено с 0.

Проблема: https://leetcode.com/problems/trips-and-users/

Мой код:


SELECT output2.day AS "Day", ROUND(output1.failed/output2.success,2) AS "Cancellation Rate"
FROM

((SELECT t1.request_at AS Day, COUNT(*) AS failed
FROM Trips T1
WHERE T1.Status != 'completed'
AND (T1.request_at BETWEEN '2013-10-01' AND '2013-10-03')
AND T1.client_id IN 
  (SELECT users_id 
   FROM users 
   WHERE role = 'client'
   AND banned = 'No')
AND t1.driver_id IN
    (SELECT users_id 
   FROM users U2 
   WHERE role = 'driver'
   AND banned = 'No')

GROUP BY t1.request_at
) AS output1

RIGHT JOIN

(SELECT t2.request_at AS Day, COUNT(*) AS success
FROM Trips T2
WHERE (T2.request_at BETWEEN '2013-10-01' AND '2013-10-03')
AND T2.client_id IN 
  (SELECT users_id 
   FROM users 
   WHERE role = 'client'
   AND banned = 'No')
AND t2.driver_id IN
    (SELECT users_id 
   FROM users 
   WHERE role = 'driver'
   AND banned = 'No')

GROUP BY t2.request_at
) AS output2

ON output1.Day = output2.Day)

GROUP BY output2.day

Мой вывод:

{"headers": ["Day", "Cancellation Rate"], "values": [["2013-10-01", 0.33], ["2013-10-02", null], ["2013-10-03", 0.50]]}

Желаемый результат:

{"headers": ["Day", "Cancellation Rate"], "values": [["2013-10-01", 0.33], ["2013-10-02", 0.00], ["2013-10-03", 0.50]]}

Я видел различные рекомендации сообщества, такие как использование функций ISNULL или IFNULL. Но оба вернули ошибку. Есть идеи?

1 Ответ

1 голос
/ 23 марта 2020

Вы можете просто использовать COALESCE() в самом внешнем запросе, чтобы превратить NULL значения в 0 s:

SELECT 
    output2.day AS "Day", 
    COALESCE(ROUND(output1.failed/output2.success,2), 0) AS "Cancellation Rate"
FROM ...

Обратите внимание, однако, что ваш запрос может быть значительно упрощен с помощью объединений и условная агрегация. Нечто подобное должно быть близко к тому, что вы хотите:

select 
    t.request_at as day, 
    avg(t.status != 'completed') as cancellation_rate
from trips t
inner join users uc 
    on uc.users_id = t.client_id and uc.role = 'client' and uc.banned = 'no'
inner join users ud 
    on ud.users_id = t.client_id and ud.role = 'driver' and ud.banned = 'no'
where t.request_at between '2013-10-01' and '2013-10-03'
group by t.request_at
...