I'm getting weird results from my query. The numbers are way off and I can't figure out why.
Heres the table structure for the tables used in the query:
CREATE TABLE IF NOT EXISTS `bookings` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`customer_id` int(11) DEFAULT NULL,
`payment_method_id` int(11) DEFAULT NULL,
`date` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`time` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`details` text COLLATE utf8mb4_unicode_ci,
`ip` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`status` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'Complete',
`booked_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `booking_products` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`booking_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`amount` int(11) NOT NULL,
`price_subtotal` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`price_total` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `booking_services` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`booking_id` int(11) NOT NULL,
`service_id` int(11) NOT NULL,
`reservations` int(11) NOT NULL,
`price_subtotal` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`price_total` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `payment_methods` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `payment_methods_name_unique` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Here is my query:
return DB::table('bookings')
->selectRaw('payment_methods.name, count(bookings.id) as bookings, (sum(booking_services.price_subtotal) + sum(booking_products.price_subtotal)) as subtotal')
->join('booking_services', 'booking_services.booking_id', '=', 'bookings.id')
->join('booking_products', 'booking_products.booking_id', '=', 'bookings.id')
->join('payment_methods', 'payment_methods.id', '=', 'bookings.payment_method_id')
->where('bookings.status', 'Complete')
->whereBetween('bookings.booked_at', [$this->carbon_from, $this->carbon_to])
->groupBy('payment_methods.id')
->orderBy('payment_methods.name')
->get();
$this->carbon_from
and $this->carbon_to
are carbon objects which work fine.
I'm trying to obtain the total bookings and a sum of the price_subtotals for each payment method. It seems to be grouping the booking products/services together rather than by each payment method like I want.
Am I missing something here?
Edit: here is the query log:
select payment_methods.name,
count(bookings.id) as bookings,
(sum(booking_services.price_subtotal) + sum(booking_products.price_subtotal)) as subtotal
from `bookings`
inner join `booking_services` on `booking_services`.`booking_id` = `bookings`.`id`
inner join `booking_products` on `booking_products`.`booking_id` = `bookings`.`id`
inner join `payment_methods` on `payment_methods`.`id` = `bookings`.`payment_method_id`
where `bookings`.`status` = ? and `bookings`.`booked_at` between ? and ?
group by `payment_methods`.`id`
order by `payment_methods`.`name` asc
I guess you are getting cross product that is why you are getting wrong numbers for aggregation, what i suggest you, calculate your sum in individual sub clauses and then join these clauses with your main query like
SELECT p.name,
COUNT(DISTINCT b.id) AS bookings,
bs.price_subtotal + bp.price_subtotal AS subtotal
FROM bookings b
INNER JOIN (
SELECT booking_id, SUM(price_subtotal) price_subtotal
FROM booking_services
GROUP BY booking_id
) bs ON b.id = bs.booking_id
INNER JOIN (
SELECT booking_id, SUM(price_subtotal) price_subtotal
FROM booking_products
GROUP BY booking_id
) bp ON b.id = bp.booking_id
INNER JOIN payment_methods p ON p.id = b.payment_method_id
WHERE b.status = ?
AND b.booked_at BETWEEN ? AND ?
GROUP BY p.name
ORDER BY p.name
I have no clue how to transform/write above query using laravel's query builder/eloquent way
尝试按bookings
表中的payment_method_id
分组:
->groupBy('bookings.payment_method_id')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.