是否可以在一个查询中计算此销售报告?考虑到包罗万象的where子句,我对SQL并没有那么热,并且无法绕过连接。
TABLES(假设外键为1-N):
TABLE contacts
id
TABLE reservations
id
created_at
contact_id
TABLE reservation_trips
id
reservation_id -- never null
amount
quantity
trip_type_id -- never null
TABLE cost_adjustments
id
reservation_trip_id -- never null
cost_type_id -- never null
TABLE trip_types
id
title
TABLE cost_types
id
title
kind
示例:
reservations.created_at >= '2013-01-01T09:00:00+00:00' AND
reservations.created_at < '2014-01-01T09:00:00+00:00' AND
reservation_trips.trip_type_id in (1, 2, 3, 4) AND
cost_adjustments.trip_type_id in (5, 6, 7, 8) AND
contact_id in (9, 10, 11, 12)
结果栏目:
trip_types.title as trip_type_title,
COUNT(DISTINCT reservations.id) as bookings, -- distinct reservations
SUM(reservations.commissions) as commissions, -- distinct reservations
SUM(reservation_trips.id) as guests, -- distinct reservation_trips
SUM(reservation_trips.amount * reservation_trips.quantity) as gross_sales, -- distinct reservation_trips
SUM(cost_adjustments.amount * cost_adjustments.quantity) as adjustments, -- distinct cost_adjustments where cost_types.kind != 'tax'
SUM(gross_sales + adjustments - commissions) as net_sales
表格列如下所示:
TRIP TYPE | BOOKINGS | GUESTS | GROSS SALES | ADJUSTMENTS | COMMISSIONS | NET SALES
谢谢!
答案 0 :(得分:0)
给它一个旋转,我认为它涵盖了它
SELECT trip_types.title as trip_type_title,
COUNT(DISTINCT reservations.id) as bookings,
SUM(reservations.commissions) as commissions, distinct reservations,
SUM(reservation_trips.id) as guests, distinct reservation_trips,
SUM(reservation_trips.amount * reservation_trips.quantity) as gross_sales,
SUM(cost_adjustments.amount * cost_adjustments.quantity) as adjustments, distinct cost_adjustments where cost_types.kind != 'tax'
SUM(gross_sales + adjustments - commissions) as net_sales
FROM trip_types tt
JOIN reservation_trips on tt.id = reservation_trips.trip_type_id
JOIN reservations on reservation_trips.reservation_id = reservations.id
JOIN cost_adjustments ON cost_adjustments.reservation_trip_id = reservation_trips.id
WHERE
reservations.created_at >= '2013-01-01T09:00:00+00:00' AND
reservations.created_at < '2014-01-01T09:00:00+00:00' AND
reservation_trips.trip_type_id in (1, 2, 3, 4) AND
cost_adjustments.trip_type_id in (5, 6, 7, 8) AND
contact_id in (9, 10, 11, 12)
GROUP BY trip_types.title
答案 1 :(得分:0)
主要问题是避免多次计算中间水平。一种方法是除以每个级别的项目数。
另一种更有效的方法是将每个级别放在它自己的子查询中,然后将它们全部加入。
这是第一种方法未经测试的刺。它可能需要一些IsNull(xxx, 0)
修正。
Select
tt.title as trip_type_title,
count(distinct r.id) as bookings,
sum(r.commissions) / count(distinct r.id) as commissions,
count(distinct rt.id) as guests, -- this seems odd, but it's in the example
sum(rt.amount * rt.quantity) / count(distinct rt.id) as gross_sales,
sum(ca.amount * ca.quantity) as adjustments,
sum(rt.amount * rt.quantity) / count(distinct rt.id) + sum(r.commissions) / count(distinct r.id) + sum(ca.amount * ca.quantity) as net_sales
From
trip_types tt
inner Join reservation_trips rt on tt.id = rt.trip_type_id
inner Join reservations r on rt.reservation_id = r.id
left outer join cost_adjustments ca on ca.reservation_trip_id = rt.id
left outer join cost_types ct on ca.cost_type_id = ct.id
Where
r.created_at >= '2013-01-01T09:00:00+00:00' and
r.created_at < '2014-01-01T09:00:00+00:00' and
rt.trip_type_id in (1, 2, 3, 4) and
ca.trip_type_id in (5, 6, 7, 8) and
contact_id in (9, 10, 11, 12) and
ct.kind != 'tax'
Group By
tt.title
答案 2 :(得分:0)
我和一位朋友交谈并想出来了。我在问题中没有解释得很好的伎俩(对不起)是搜索应该包括在我的例子where子句中修补搜索条件的所有旅行和调整。因此,您必须使用“with”查询才能首先找到相应的预订,然后根据该预测过滤行程和调整。非常棘手。
以下是我们在生产中实际使用的略有不同的字段时发现的答案,但操作效果相同:
with reservations_search as (
select
distinct reservations.id
from
reservations
left outer join contacts on
reservations.contact_id = contacts.id
left outer join reservation_trips on
reservations.id = reservation_trips.reservation_id
left outer join cost_adjustments on
reservation_trips.id = cost_adjustments.cost_target_id
where
#{Reservation.warez_sql(params)[0].join(' AND ')}
)
select
res_level.breeze_id,
res_level.trip_category_id,
res_level.bookings,
res_level.commissions,
res_level.guests,
adjustments_level.adjustments,
res_level.gross_sales + adjustments_level.adjustments - res_level.commissions as net_sales
FROM
(select
breeze_id,
trip_category_id,
sum(trip_commission) as commissions,
count(distinct reservation_id) as bookings,
count(reservation_trip_id) as guests,
sum(gross_sales) as gross_sales
from
-- Commissions by reservation_trips.id
(select
reservations.id as reservation_id,
reservation_trips.id as reservation_trip_id,
reservation_trips.amount * reservation_trips.quantity as gross_sales,
case
when reservations.total_cost_commissionable > 0
then coalesce(reservations.commission, 0) * reservation_trips.total_cost_commissionable / reservations.total_cost_commissionable
else 0
end as trip_commission,
trip_types.breeze_id,
trip_types.trip_category_id
from
reservations
left outer join contacts on
reservations.contact_id = contacts.id
left outer join reservation_trips on
reservations.id = reservation_trips.reservation_id
left outer join trip_types on
reservation_trips.trip_type_id = trip_types.id
where
reservations.id in (select id from reservations_search) ) as trip_level
group by
breeze_id,
trip_category_id) as res_level
-- Adjustments
left outer join
(select
trip_types.breeze_id,
sum(cost_adjustments.amount * cost_adjustments.quantity) as adjustments
from
reservation_trips
left outer join reservations on
reservation_trips.reservation_id = reservations.id
left outer join cost_adjustments on
cost_target_type = 'ReservationTrip' and
reservation_trips.id=cost_adjustments.cost_target_id
left outer join cost_types on
cost_type_id = cost_types.id
left outer join trip_types on
reservation_trips.trip_type_id=trip_types.id
where
reservations.id in (select id from reservations_search) and
cost_types.commissionable IS TRUE
group by
trip_types.breeze_id) as adjustments_level on
res_level.breeze_id = adjustments_level.breeze_id