Subject Re: [firebird-support] CTE 101
Author Vlad
> From your design-view screenshots, it looks like that's already the case.
>
> select a_name, q_name, enq_tot, enq_avg, enq_max, enq_low, enq_mid, enq_hi, pct_low, pct_mid,
> pct_hi, enq.serv_time, enq.serv_date, enq.ticket_num
> from (
> select a_name, q_name, enq_tot, enq_avg, enq_max, enq_low, enq_mid, enq_hi,
> case when enq_tot > 0 then 100 * enq_low / enq_tot else 0 end as pct_low,
> case when enq_tot > 0 then 100 * enq_mid / enq_tot else 0 end as pct_mid,
> case when enq_tot > 0 then 100 * enq_hi / enq_tot else 0 end as pct_hi,
> (select first 1 badenq.id from enquiries badenq where badenq.queue_id = q_id order by serv_time
> desc) as enq_bad_id
> from (
> select
> area.id a_id,
> area.name a_name,
> queue.id q_id,
> queue.name q_name,
> count(enquiries.*) enq_tot,
> avg(enquiries.serv_time) enq_avg,
> max(enquiries.serv_time) enq_max,
> count(case when enquiries.serv_time < area.lower_bound then 1 end) enq_low,
> count(case when enquiries.serv_time between area.lower_bound and area.upper_bound then 1 end)
> enq_mid,
> count(case when enquiries.serv_time > area.upper_bound then 1 end) enq_hi
> from
> enquiries
> left join queue on queue.id = enquiries.queue_id
> left join area on area.id = queue.area_id
> where
> enquiries.serv_date between ... and ...
> group by a_id, q_id, area.name, queue.name
> ) as z
> ) as y
> left join enquiries enq on enq.id = y.enq_bad_id
> ;

Compare

WITH
Z as
(
select
area.id a_id,
area.name a_name,
queue.id q_id,
queue.name q_name,
count(enquiries.*) enq_tot,
avg(enquiries.serv_time) enq_avg,
max(enquiries.serv_time) enq_max,
count(case when enquiries.serv_time < area.lower_bound then 1
end) enq_low,
count(case when enquiries.serv_time between area.lower_bound and
area.upper_bound then 1 end)
enq_mid,
count(case when enquiries.serv_time > area.upper_bound then 1
end) enq_hi

from
enquiries
left join queue on queue.id = enquiries.queue_id
left join area on area.id = queue.area_id
where
enquiries.serv_date between ... and ...
group by a_id, q_id, area.name, queue.name
),

Y as
(
select
a_name, q_name, enq_tot, enq_avg, enq_max, enq_low, enq_mid, enq_hi,
case when enq_tot > 0 then 100 * enq_low / enq_tot else 0 end as
pct_low,
case when enq_tot > 0 then 100 * enq_mid / enq_tot else 0 end as
pct_mid,
case when enq_tot > 0 then 100 * enq_hi / enq_tot else 0 end as
pct_hi,
(select first 1 badenq.id from enquiries badenq
where badenq.queue_id = q_id order by serv_time desc) as enq_bad_id

from Z
)

select
a_name, q_name, enq_tot, enq_avg, enq_max, enq_low, enq_mid,
enq_hi, pct_low, pct_mid, pct_hi,
enq.serv_time, enq.serv_date, enq.ticket_num

from Y left join enquiries enq
on enq.id = y.enq_bad_id


Which one is easier to write and understand ? :)

Regards,
Vlad