2014-10-02 87 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