我的查询是这样的:
SELECT a.id, a.store_id, a.name, a.total_sold, a.updated_at, b.name AS store_name
FROM products a
JOIN stores b ON b.id = a.store_id
JOIN products_categories c ON c.product_id = a.id
WHERE a.status = 1 AND a.stock > 0 AND c.category_id = 4
如果执行了查询,结果如下:
+----+----------+------------+------------+---------------------+------------+
| id | store_id | name | total_sold | updated_at | store_name |
+----+----------+------------+------------+---------------------+------------+
| 1 | 1 | product 1 | 1 | 2017-07-11 05:53:41 | store 1 |
| 2 | 1 | product 2 | 2 | 2017-07-11 06:53:41 | store 1 |
| 3 | 1 | product 3 | 3 | 2017-07-11 07:53:41 | store 1 |
| 4 | 2 | product 4 | 4 | 2017-07-11 08:53:41 | store 2 |
| 5 | 2 | product 5 | 5 | 2017-07-11 09:53:41 | store 2 |
| 6 | 3 | product 6 | 6 | 2017-07-11 10:53:41 | store 3 |
| 7 | 3 | product 7 | 7 | 2017-07-11 11:53:41 | store 3 |
| 8 | 3 | product 8 | 8 | 2017-07-11 12:53:41 | store 3 |
| 9 | 4 | product 9 | 9 | 2017-07-11 13:53:41 | store 4 |
| 10 | 5 | product 10 | 0 | 2017-07-11 14:53:41 | store 5 |
| 11 | 6 | product 11 | 1 | 2017-07-11 15:53:41 | store 6 |
| 12 | 7 | product 12 | 2 | 2017-07-11 16:53:41 | store 7 |
| 13 | 8 | product 13 | 3 | 2017-07-11 17:53:41 | store 8 |
| 14 | 8 | product 14 | 4 | 2017-07-11 18:53:41 | store 8 |
| 15 | 2 | product 15 | 5 | 2017-07-11 19:53:41 | store 2 |
| 16 | 2 | product 16 | 6 | 2017-07-11 20:53:41 | store 2 |
| 17 | 3 | product 17 | 7 | 2017-07-11 21:53:41 | store 3 |
+----+----------+------------+------------+---------------------+------------+
我希望数据按store_id分组,并获取最多的total_sold和最新的updated_at
我试着这样:
SELECT a.id, a.store_id, a.name, a.total_sold, a.updated_at, b.name AS store_name
FROM products a
JOIN stores b ON b.id = a.store_id
JOIN products_categories c ON c.product_id = a.id
WHERE a.status = 1 AND a.stock > 0 AND c.category_id = 4 AND
a.id = (SELECT e.id
FROM products e
JOIN stores b ON b.id = e.store_id
JOIN products_categories c ON c.product_id = e.id
WHERE e.status = 1 AND e.stock > 0 AND c.category_id = 4 AND e.store_id = a.store_id
ORDER BY e.total_sold DESC, e.updated_at DESC
LIMIT 1)
它有效
结果如下:
+----+----------+------------+------------+---------------------+------------+
| id | store_id | name | total_sold | updated_at | store_name |
+----+----------+------------+------------+---------------------+------------+
| 3 | 1 | product 3 | 3 | 2017-07-11 07:53:41 | store 1 |
| 8 | 3 | product 8 | 8 | 2017-07-11 12:53:41 | store 3 |
| 9 | 4 | product 9 | 9 | 2017-07-11 13:53:41 | store 4 |
| 10 | 5 | product 10 | 0 | 2017-07-11 14:53:41 | store 5 |
| 11 | 6 | product 11 | 1 | 2017-07-11 15:53:41 | store 6 |
| 12 | 7 | product 12 | 2 | 2017-07-11 16:53:41 | store 7 |
| 14 | 8 | product 14 | 4 | 2017-07-11 18:53:41 | store 8 |
| 16 | 2 | product 16 | 6 | 2017-07-11 20:53:41 | store 2 |
+----+----------+------------+------------+---------------------+------------+
但似乎我的查询太长,可能不那么快
是否有更好的解决方案可以让查询更快更短?
更新:
我在下面提供了示例数据,并提供了相同的方法:http://sqlfiddle.com/#!9/3324a0/4
CREATE TABLE IF NOT EXISTS `stores` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `stores` (`id`, `name`) VALUES
('1', 'store 1'),
('2', 'store 2'),
('3', 'store 3'),
('4', 'store 4'),
('5', 'store 5'),
('6', 'store 6'),
('7', 'store 7'),
('8', 'store 8'),
('9', 'store 9'),
('10', 'store 10');
CREATE TABLE IF NOT EXISTS `products` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`store_id` int(10) unsigned NOT NULL,
`name` varchar(70) COLLATE utf8_unicode_ci NOT NULL,
`total_sold` int(11) NOT NULL DEFAULT '0',
`stock` int(11) NOT NULL DEFAULT '0',
`status` smallint(6) NOT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `products_store_id_foreign` (`store_id`),
KEY `products_name_index` (`name`),
CONSTRAINT `products_store_id_foreign` FOREIGN KEY (`store_id`) REFERENCES `stores` (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `products` (`id`, `store_id`, `name`, `total_sold`, `stock`, `status`, `updated_at`) VALUES
('1', '1', 'product 1', '1', '1', '1', '2017-07-11 05:53:41'),
('2', '1', 'product 2', '2', '1', '1', '2017-07-11 06:53:41'),
('3', '1', 'product 3', '3', '1', '1', '2017-07-11 07:53:41'),
('4', '2', 'product 4', '4', '1', '1', '2017-07-11 08:53:41'),
('5', '2', 'product 5', '5', '1', '1', '2017-07-11 09:53:41'),
('6', '3', 'product 6', '6', '1', '1', '2017-07-11 10:53:41'),
('7', '3', 'product 7', '7', '1', '1', '2017-07-11 11:53:41'),
('8', '3', 'product 8', '8', '1', '1', '2017-07-11 12:53:41'),
('9', '4', 'product 9', '9', '1', '1', '2017-07-11 13:53:41'),
('10', '5', 'product 10', '0', '1', '1', '2017-07-11 14:53:41'),
('11', '6', 'product 11', '1', '1', '1', '2017-07-11 15:53:41'),
('12', '7', 'product 12', '2', '1', '1', '2017-07-11 16:53:41'),
('13', '8', 'product 13', '3', '1', '1', '2017-07-11 17:53:41'),
('14', '8', 'product 14', '4', '1', '1', '2017-07-11 18:53:41'),
('15', '2', 'product 15', '5', '1', '1', '2017-07-11 19:53:41'),
('16', '2', 'product 16', '6', '1', '1', '2017-07-11 20:53:41'),
('17', '3', 'product 17', '7', '1', '1', '2017-07-11 21:53:41');
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `categories` (`id`, `name`) VALUES
('1', 'category 1'),
('2', 'category 2'),
('3', 'category 3'),
('4', 'category 4');
CREATE TABLE IF NOT EXISTS `products_categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`product_id` int(10) unsigned NOT NULL,
`category_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `products_categories_product_id_foreign` (`product_id`),
KEY `products_categories_category_id_foreign` (`category_id`),
CONSTRAINT `products_categories_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`),
CONSTRAINT `products_categories_product_id_foreign` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `products_categories` (`id`, `product_id`, `category_id`) VALUES
('1', '1', '4'),
('2', '2', '4'),
('3', '3', '4'),
('4', '4', '4'),
('5', '5', '4'),
('6', '6', '4'),
('7', '7', '4'),
('8', '8', '4'),
('9', '9', '4'),
('10', '10', '4'),
('11', '11', '4'),
('12', '12', '4'),
('13', '13', '4'),
('14', '14', '4'),
('15', '15', '4'),
('16', '16', '4'),
('17', '17', '4');
你可以尝试一下,也许可以帮助我做出更短更快的查询:)
答案 0 :(得分:1)
SELECT a.*
FROM products a
JOIN
( SELECT x.store_id
, x.total_sold
, MAX(x.updated_at) updated_at
FROM products x
JOIN
( SELECT store_id
, MAX(total_sold) total_sold
FROM products
GROUP
BY store_id
) y
ON y.store_id = x.store_id
AND y.total_sold = x.total_sold
GROUP
BY store_id
, total_sold
) b
ON b.store_id = a.store_id
AND b.total_sold = a.total_sold
AND b.updated_at = a.updated_at;
+----+----------+------------+------------+-------+--------+---------------------+
| id | store_id | name | total_sold | stock | status | updated_at |
+----+----------+------------+------------+-------+--------+---------------------+
| 3 | 1 | product 3 | 3 | 1 | 1 | 2017-07-11 07:53:41 |
| 16 | 2 | product 16 | 6 | 1 | 1 | 2017-07-11 20:53:41 |
| 8 | 3 | product 8 | 8 | 1 | 1 | 2017-07-11 12:53:41 |
| 9 | 4 | product 9 | 9 | 1 | 1 | 2017-07-11 13:53:41 |
| 10 | 5 | product 10 | 0 | 1 | 1 | 2017-07-11 14:53:41 |
| 11 | 6 | product 11 | 1 | 1 | 1 | 2017-07-11 15:53:41 |
| 12 | 7 | product 12 | 2 | 1 | 1 | 2017-07-11 16:53:41 |
| 14 | 8 | product 14 | 4 | 1 | 1 | 2017-07-11 18:53:41 |
+----+----------+------------+------------+-------+--------+---------------------+
8 rows in set (0.03 sec)