2017-10-04 155 views
0

我这样的查询:如何根据mysql中的特定字段对组数据进行排序?

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 | 
+----+----------+------------+------------+---------------------+------------+ 

,但似乎我的查询是太长,也许更少快速

是否有更好的解决方案,使查询速度更快,更短?

更新

我在下面提供的样本数据,并sqlfiddle的一样: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

因为您在产品中有store_id,因此在子查询中存储的联接看起来没有必要,因为您已经在子查询中完成了此操作,并且a.status = 1 AND a.stock> 0 AND c.category_id = 4在主查询中的where部分看起来没有必要,因为您已经在子查询中完成了此操作。 –

+0

@SuccessMan如上所述,数据集不代表问题。另外,请参阅我的原始评论。显然,名称和商店名称无关紧要,因此可以省略。 – Strawberry

回答

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) 
+0

好的。谢谢。但为什么没有加入products_categories表?除此之外,也没有这样的条件:'WHERE a.status = 1 AND a.stock> 0和c.category_id = 4' –

+1

@SuccessMan,因为我看不到写点琐碎的点 – Strawberry

+0

你是什么意思?但我已经在sqlfiddle中提供了示例数据。应该说明我的观点 –

相关问题