2014-10-02 51 views
1

我有一个电子商务表“订单”,表中有'状态'记录和'水果'记录。我试图(和失败)创建一个查询,将返回每个州的结果和前3个最受欢迎的水果,按顺序显示。带嵌套列表的MySQL查询

所以, '订单' 表看起来像这样:

id State Fruit 
---------------- 
1 CA  grape 
2 FL  orange 
3 CA  grape 
4 FL  grapefruit 
5 CA  orange 
6 CA  grape 
7 FL  orange 
8 CA  peach 
9 CA  orange 
10 FL  orange 
11 FL  grapefruit 
12 FL  peach 
etc etc etc 

在此表上查询的结果将是:

the_state the_fruits 
------------------------ 
CA   grape, orange, peach 
FL   orange, grapefruit, peach 

我尝试这样做:

SELECT state as the_state, 
(select count(id) as count, fruit from orders where state = the_state order by count(id) limit 3 ) as the_fruits 
FROM orders 
group by fruit 
order by count(id) DESC 

但是,这是无效的有效查询,我不知道我在正确的轨道上

回答

1

在MySQL中分组数据的限制结果是相当困难的。在各种线程上有很多解决方案,但它可能取决于您所拥有的数据类型和数量。

以下可能是最简单的解决方案。

mysql> INSERT INTO orders VALUES 
    -> ('1', 'CA', 'grape'), 
    -> ('2', 'FL', 'orange'), 
    -> ('3', 'CA', 'grape'), 
    -> ('4', 'FL', 'grapefruit'), 
    -> ('5', 'CA', 'orange'), 
    -> ('6', 'CA', 'grape'), 
    -> ('7', 'FL', 'orange'), 
    -> ('8', 'CA', 'peach'), 
    -> ('9', 'CA', 'orange'), 
    -> ('10', 'FL', 'orange'), 
    -> ('11', 'FL', 'grapefruit'), 
    -> ('12', 'FL', 'peach'), 
    -> ('13', 'CA', 'apple'), 
    -> ('14', 'FL', 'apple'); 
Query OK, 14 rows affected (0.03 sec) 
Records: 14 Duplicates: 0 Warnings: 0 

mysql> select state, fruit, count(fruit) cf from orders group by state, fruit order by state, cf desc; 
+-------+------------+----+ 
| state | fruit  | cf | 
+-------+------------+----+ 
| CA | grape  | 3 | 
| CA | orange  | 2 | 
| CA | peach  | 1 | 
| CA | apple  | 1 | 
| FL | orange  | 3 | 
| FL | grapefruit | 2 | 
| FL | peach  | 1 | 
| FL | apple  | 1 | 
+-------+------------+----+ 
8 rows in set (0.00 sec) 

SELECT state 
    , SUBSTRING_INDEX(GROUP_CONCAT(fruit ORDER BY cf DESC, fruit),',',3) top3 
    FROM 
    (SELECT state 
      , fruit 
      , COUNT(fruit) cf 
     FROM orders 
     GROUP 
      BY state 
      , fruit 
    ) t1 
GROUP 
    BY state; 
+-------+-------------------------+ 
| state | top3     | 
+-------+-------------------------+ 
| CA | grape,orange,peach  | 
| FL | orange,grapefruit,apple | 
+-------+-------------------------+ 
2 rows in set (0.00 sec) 
+0

我的表实际上有很多的水果,这查询不返回顶部3.返回随机3.与国家,水果的表中的第一个查询,CF是正确的。 – lilbiscuit 2014-10-06 13:03:52

+0

我更新了group_concat函数,以排列前3名,按水果名排序的关系。让我知道这个是否奏效。 – 2014-10-08 22:50:39

0

正如doog所指出的那样,我以前的解决方案处理联系不好。这是一个替代方案,使用前面提到的变量。这也是瞬息万变......

DROP TABLE IF EXISTS orders; 

    CREATE TABLE orders 
    (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
    , state CHAR(2) 
    , fruit VARCHAR(20) NOT NULL 
); 

    INSERT INTO orders VALUES 
    (1 ,'CA','grape'), 
    (2 ,'FL','orange'), 
    (3 ,'CA','grape'), 
    (4 ,'FL','grapefruit'), 
    (5 ,'CA','orange'), 
    (6 ,'CA','grape'), 
    (7 ,'FL','orange'), 
    (8 ,'CA','peach'), 
    (9 ,'CA','orange'), 
    (10 ,'FL','orange'), 
    (11 ,'FL','grapefruit'), 
    (12 ,'FL','peach'), 
    (13 ,'FL','banana'); 

    SELECT state 
     , fruit 
     , total 
     , IF(@prev_state = state, IF(@prev_total=total,@rank,@rank:[email protected]+1),@rank:=1) rank 
     , @prev_state := state 
     , @prev_total := total 
    FROM 
     (SELECT state 
       , fruit 
       , COUNT(*) total 
      FROM orders 
      GROUP 
      BY state 
       , fruit 
     ) x 
     , (SELECT @prev_state := null, @prev_total:=null, @rank := 0) vars 
    ORDER 
     BY state,total DESC; 

    +-------+------------+-------+------+----------------------+----------------------+ 
    | state | fruit  | total | rank | @prev_state := state | @prev_total := total | 
    +-------+------------+-------+------+----------------------+----------------------+ 
    | CA | grape  |  3 | 1 | CA     |     3 | 
    | CA | orange  |  2 | 2 | CA     |     2 | 
    | CA | peach  |  1 | 3 | CA     |     1 | 
    | FL | orange  |  3 | 1 | FL     |     3 | 
    | FL | grapefruit |  2 | 2 | FL     |     2 | 
    | FL | banana  |  1 | 3 | FL     |     1 | 
    | FL | peach  |  1 | 3 | FL     |     1 | 
    +-------+------------+-------+------+----------------------+----------------------+ 
+0

不幸的是,如果你添加另一个单数水果,你将有两排排名第4的球员,而没有排名第三的球员,这意味着无法将其限制在前三名。 – 2014-10-02 18:30:34