0

I have created this query to solve this problem,

SELECT c.ra as Day, round(count(cancelled) / Count(*),2) as "Cancellation Rate" FROM  
(
    select a.Id, a.ra, a.Status as status, b.Status as cancelled FROM 
    (
        select Id, Client_Id, Driver_Id, Status, Request_at as ra from Trips t
            where not exists 
            (
                select 1 from users u
                where (t.Client_Id = u.Users_Id or t.Driver_Id = u.Users_Id)
                and u.banned = 'Yes'
            )
    ) a LEFT JOIN 
    (
        select Id, Client_Id, Driver_Id, Status, Request_at as ra from Trips t
            where not exists 
            (
                select 1 from users u
                where (t.Client_Id = u.Users_Id or t.Driver_Id = u.Users_Id)
                and u.banned = 'Yes'
            ) and (t.Status = 'cancelled_by_driver' or t.status = 'cancelled_by_client')
    ) b on a.Id = b.Id
) c GROUP BY c.ra

To make that query more concise, I changed it into the following, but that doesn't work. So, my question is, what is the right way of making such queries more concise?

SELECT c.ra as Day, round(count(cancelled) / Count(*),2) as "Cancellation Rate" FROM  
(
    select a.Id, a.ra, a.Status as status, b.Status as cancelled FROM 
    (
        select Id, Client_Id, Driver_Id, Status, Request_at as ra from ( 
            select * from Trips t
            where not exists 
            (
                select 1 from users u
                where (t.Client_Id = u.Users_Id or t.Driver_Id = u.Users_Id)
                and u.banned = 'Yes'
            )
        ) t1
    ) a LEFT JOIN 
    (
        select Id, Client_Id, Driver_Id, Status, Request_at as ra from t1
            WHERE (Status = 'cancelled_by_driver' or Status = 'cancelled_by_client')
    ) b on a.Id = b.Id
) c GROUP BY c.ra
2
  • Please provide sample data, desired results, and an explanation of what you are trying to accomplish. Commented Nov 22, 2020 at 13:05
  • I have added the link of the problem now on the first line. Commented Nov 22, 2020 at 13:06

1 Answer 1

1

If I understand correctly, I would just use conditional aggregation:

SELECT Date(request_at) AS Day, 
       Round(Avg(status IN ( 'cancelled_by_driver', 
                             'cancelled_by_client' )), 2) AS 
       "Cancellation Rate" 
FROM   trips t 
WHERE  NOT EXISTS (SELECT 1 
                   FROM   users u 
                   WHERE  u.users_id IN ( t.client_id, t.driver_id ) 
                          AND u.banned = 'Yes') 
GROUP  BY day; 

In your second version t1 is simply not defined. If you wanted to re-use a subquery this way, you would need to use a CTE:

with t1 as (
     . . .
    )
select . . .

Then you could reference t1 multiple times in the query.

Sign up to request clarification or add additional context in comments.

2 Comments

I see, your solution is correct, but the problem requires round off to 2 digits after the decimal. But of course that can be easily achieved by using the round function. Also its Request_at rather than requested_at.
@MetallicPriest . . . I trust that you can make those changes.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.