MySQL Group BY优先使用哪个分组记录返回

时间:2016-09-06 11:38:51

标签: mysql sql phpmyadmin group-by

我有以下两个表:

Products
+--------------------------+--------------+------+-----+---------+-------+
| Field                    | Type         | Null | Key | Default | Extra |
+--------------------------+--------------+------+-----+---------+-------+
| id                       | int(6)       | NO   | PRI | NULL    |       |
| productName              | varchar(255) | YES  |     | NULL    |       |
| landColour               | varchar(255) | YES  |     | NULL    |       |
+--------------------------+--------------+------+-----+---------+-------+

Skus
+--------------+---------------+------+-----+---------+-------+
| Field        | Type          | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+-------+
| id           | int(11)       | NO   | PRI | NULL    |       |
| product_id   | int(11)       | NO   | MUL | NULL    |       |
| colour       | varchar(255)  | NO   | MUL | NULL    |       |
| fit          | varchar(255)  | NO   | MUL | NULL    |       |
| size         | decimal(10,1) | NO   | MUL | NULL    |       |
| stock_status | varchar(255)  | NO   | MUL | NULL    |       |
| image        | varchar(255)  | NO   |     | NULL    |       |
+--------------+---------------+------+-----+---------+-------+

Product Data
+----+--------------+------------+
| id | productName  | landColour |
+----+--------------+------------+
| 1  | Running Shoe | Red        |
| 2  | Smart Shoe   | Green      |
| 3  | Casual Shoe  | Blue       |
+----+--------------+------------+

Sku Data
+----+------------+--------+--------------+------+--------------+----------------+
| id | product_id | colour | fit          | size | stock_status | image          |
+----+------------+--------+--------------+------+--------------+----------------+
| 1  | 1          | Red    | Standard Fit | 5    | In-Stock     | /img/img1.jpg  |
| 2  | 1          | Green  | Standard Fit | 5    | In-Stock     | /img/img2.jpg  |
| 3  | 1          | Blue   | Standard Fit | 5    | In-Stock     | /img/img3.jpg  |
| 4  | 1          | Red    | Standard Fit | 6    | Out-of-Stock | /img/img4.jpg  |
| 5  | 1          | Green  | Standard Fit | 6    | In-Stock     | /img/img5.jpg  |
| 6  | 1          | Blue   | Standard Fit | 6    | In-Stock     | /img/img6.jpg  |
| 7  | 2          | Red    | Standard Fit | 5    | Out-of-Stock | /img/img7.jpg  |
| 8  | 2          | Green  | Standard Fit | 5    | Out-of-Stock | /img/img8.jpg  |
| 9  | 2          | Blue   | Standard Fit | 5    | Out-of-Stock | /img/img9.jpg  |
| 10 | 2          | Red    | Standard Fit | 6    | In-Stock     | /img/img10.jpg |
| 11 | 2          | Green  | Standard Fit | 6    | Out-of-Stock | /img/img11.jpg |
| 12 | 2          | Blue   | Standard Fit | 6    | In-Stock     | /img/img12.jpg |
| 13 | 3          | Red    | Standard Fit | 5    | In-Stock     | /img/img13.jpg |
| 14 | 3          | Green  | Standard Fit | 5    | In-Stock     | /img/img14.jpg |
| 15 | 3          | Blue   | Standard Fit | 5    | In-Stock     | /img/img15.jpg |
| 16 | 3          | Red    | Standard Fit | 6    | In-Stock     | /img/img16.jpg |
| 17 | 3          | Green  | Standard Fit | 6    | In-Stock     | /img/img17.jpg |
| 18 | 3          | Blue   | Standard Fit | 6    | In-Stock     | /img/img18.jpg |
+----+------------+--------+--------------+------+--------------+----------------+

Desired Results
+------------+--------+--------+------+----------------+
| product_id | sku_id | colour | size | image          |
+------------+--------+--------+------+----------------+
| 1          | 1      | Red    | 5    | /img/img1.jpg  |
| 1          | 5      | Green  | 6    | /img/img5.jpg  |
| 2          | 10     | Red    | 6    | /img/img10.jpg |
| 3          | 15     | Blue   | 5    | /img/img15.jpg |
| 3          | 18     | Blue   | 6    | /img/img18.jpg |
+------------+--------+--------+------+----------------+

我正在尝试检索fit = 'Standard Fit'stock_status = 'In-Stock'按大小分组的所有skus,但如果skus.colour字段与products.landColour列匹配,那么这是我首选的记录。我们的目标是,对于每种产品,我都会有库存记录,每种尺寸都有库存,最好是与地面颜色相同的颜色。这是我试过的几乎是正确但不完全的,有些记录即使有库存也没有退货:

SELECT 
    p.productName AS name, 
    p.id AS product_id, 
    IF(s1.size IS NULL, s2.size, s1.size) AS size, 
    IF(s1.image IS NULL, s2.image, s1.image) AS image, 
    IF(s1.fit IS NULL, s2.fit, s1.fit) AS fit 
FROM products p 
LEFT JOIN skus s1 ON 
    p.id = s1.product_id 
    AND s1.stock_status = 'In-Stock' 
    AND s1.colour = p.landColour AND 
    s1.fit = 'Standard Fit' 
LEFT JOIN skus s2 ON 
    p.id = s2.product_id 
    AND s2.stock_status = 'In-Stock' 
    AND s2.fit = 'Standard Fit' 
GROUP BY size 
HAVING ( image IS NOT NULL AND size IS NOT NULL )

2 个答案:

答案 0 :(得分:0)

我没有完全按照你要做的去做。然而,这是非常可疑的:

GROUP BY size 

我怀疑你想要:

GROUP BY p.productName, p.id

答案 1 :(得分:0)

我会使用SINGLE加入并添加一列来表示您的"首选"条目。然后您的订单可以基于所有首选推送到顶部和所有其他人跟随。在这种情况下,对于每个产品,我只有一个标志,如果找到首选颜色,它得到1(以后排序),否则2在#1首选之后。

SELECT 
      p.productName AS name, 
      p.id product_id, 
      s1.size, 
      s1.image, 
      s1.fit,
      if( s1.colour = p.landColour, 1, 2 ) as PreferredFlag
   FROM 
      products p 
         LEFT JOIN skus s1 
            ON p.id = s1.product_id
           AND s1.stock_status = 'In-Stock' 
           AND s1.fit = 'Standard Fit' 
   GROUP BY 
      size,
      if( s1.colour = p.landColour, 1, 2 ) as PreferredFlag
   HAVING 
          image IS NOT NULL 
      AND size IS NOT NULL
   order by
      if( s1.colour = p.landColour, 1, 2 ),
      size

现在,除了大小之外,您没有进行任何真正保证组合的聚合,这只会导致任何给定大小的第一个产品名称和ID符合条件。您可能实际上需要调整到类似下面的内容。在这种情况下,我得到一个与所需颜色匹配的计数的SUM作为首选标志COUNTER。但也有一个COUNT,其中有多少给定的产品名称和尺寸实际可用,无论颜色如何。

最终的ORDER BY基于......如果匹配颜色的总数是> 0,然后它得到1,否则为2用于排序目的,然后按大小排序。

SELECT 
      p.productName AS name, 
      p.id product_id, 
      s1.size, 
      s1.image, 
      s1.fit,
      COUNT(*) as NumberAvailable,
      SUM( if( s1.colour = p.landColour, 1, 0 )) as PreferredFlag
   FROM 
      products p 
         LEFT JOIN skus s1 
            ON p.id = s1.product_id
           AND s1.stock_status = 'In-Stock' 
           AND s1.fit = 'Standard Fit' 
   GROUP BY 
      p.productName
   HAVING 
          image IS NOT NULL 
      AND size IS NOT NULL
   order by
      if( SUM( if( s1.colour = p.landColour, 1, 0 )) > 0, 1, 2 ) as PreferredFlag,
      size