2017-10-04 105 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中提供了示例數據。應該說明我的觀點 –

相關問題