1

是否可以在一次查询中计算此销售报告?考虑到包罗万象的 where 子句,我对 SQL 并没有那么热情,并且在将我的头绕在连接上时遇到了麻烦。

表(假设外键为 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

谢谢!

4

3 回答 3

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
于 2013-09-13T22:22:12.963 回答
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
于 2013-09-13T23:03:10.887 回答
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
于 2013-09-15T02:17:40.250 回答