2012-03-18 62 views
0

我真的很苦恼,现在已经很久了,并且已经在这里问了两个问题!生气 - 我需要根据条件对结果进行分组

因此,这里有一个希望更明确的问题。

我有一个包含几千种产品的产品数据库。

产品可以按item分组,以便不会在我的搜索结果中显示基本相同但结尾不同的多个项目。

所以,一个简单的select查询看起来像:

SELECT * FROM products GROUP BY item 

这会给我所有的产品只显示了每个项目(该想法是,观察客户点击别的东西来显示所有的完成选项)

我可以使用类似

SELECT *, GROUP_CONCAT(finishes) FROM products GROUP BY item 

但让我完成选项...这里就是我有问题

在我的搜索结果页面中,分组的“随机”顺序对我来说并不好。我需要能够有从小组条款取决于以下condtions

- If there is no stock of any finish, then display the cheapest option 
- If there is stock, then display the cheapest item which is in stock 

获取只是一个ID是不行的,我需要完整的记录显示的项目,所以在某种程度上我需要的是一个条件语句确定分组记录的呈现顺序,以确保我从recordset获得的项目符合上述标准。

我根本无法解决如何做到这一点,我尝试了数百万个不同的INNER JOIN和'CASE场景,但却无法让它工作。

这里就是我得今天上午:

​​

这是给我的结果,而是形成原因,一些项目被排除在结果和排序顺序仍然是不正确的。

要回答以下@DRapp,这里的一些基本的样本数据

item  | price  |  finish   | totalStock 

item 1 |  £1  |  red   |  2 
item 1 |  £1  |  blue   |  1 
item 1 |  £1.50 |  blue & red |  1 

item 2 |  £2  |  red   |  0 
item 2 |  £3  |  blue   |  1 

item 3 |  £3.50 |  blue & red |  1 
item 3 |  £1  |  red   |  0 
item 3 |  £2  |  blue   |  1 

item 4 |  £4.50 |  blue & red |  1 

item 5 |  £1.50 |  blue   |  0 
item 5 |  £2.50 |  green  |  0 
item 5 |  £0.50 |  orange  |  0 

我想看到的结果是:

  • 项目1,红(sumTotalStock = 4) - “红色和蓝色的股票都最廉价的&。示任一结果是好的,但为100%的完美,显示出红色作为库存是最大
  • 项目2,蓝色(sumTotalStock = 1) - ”蓝色是唯一的完成的库存
  • 项目3,蓝(sumTotalStock = 2) - “显示蓝色,因为它是最便宜的股票
  • 项目4,蓝色&红(sumTotalStock = 1)-'there没有完成的选项,所以只显示这一块,无论股票/价格
  • item 5,orange(sumTotalStock = 0) - 'none i n股票,但显示橙色,因为它是最便宜的。

显然有更多的数据,以实际显示比刚跑完,价格,产品说明等也,这可能取决于完成,因此我也需要得到完整的记录,但是这个数据的例子应该解释原则。

+0

在Oracle中,我会写一个USER DEFINED AGGREGATE FUNCTION - 不确定是否有关于mysql。也许写一个函数,将该项目作为参数,然后返回一个完成的字符串。 – Randy 2012-03-18 13:51:45

+0

很确定这是一个最大的每组问题的例子。搜索带标签的问题以查看可能有所帮助的一些解决方案:http:// stackoverflow。com/questions/tagged/most-n-group- – 2012-03-18 13:53:12

+0

您可以转储一些示例数据,包括没有完成的示例数据以及定价样本等。然后展示你想要什么样的最终结果(如果Martijn的回答不是你的最终结果) – DRapp 2012-03-18 14:41:34

回答

0

这应该做你想要使用一个“简单”左连接和没有嵌套的选择;您的排序标准使查询看起来有点庞大:)

SELECT p1.* 
FROM Products p1 
LEFT JOIN Products p2 
    ON p1.item=p2.item AND 
    (IF(p1.totalstock,1,0) < IF(p2.totalstock,1,0) OR 
     (IF(p1.totalstock,1,0) = IF(p2.totalstock,1,0) AND 
     p1.price > p2.price) OR 
     (p1.price = p2.price AND 
     p1.totalstock < p2.totalstock) OR 
     (p1.price = p2.price AND 
     p1.totalstock = p2.totalstock AND 
     p1.id > p2.id)) 
WHERE p2.id IS NULL 

演示here

+0

那个厕所ks与我试图实现的类似,你能解释一下'WHERE p2.id IS NULL'吗?另外,这是在哪里把我的主要搜索条件'WHERE'子句? – 2012-03-18 16:11:13

+0

@JamieHartnoll基本上它使用'LEFT JOIN'进行排序,试图将每个p1与“更好”的p2进行匹配。如果没有更好的p2,那么p2.id是NULL。你是否有典型的WHERE条件? – 2012-03-18 16:21:26

+0

优秀,这似乎是工作!对于查询某个项目,我正在执行'WHERE p1.item ='SEARCH TEXT''这似乎可行,我需要的最常见的其他应用程序是查询类别字段,品牌以及您提到的价格(我排除了原始问题的类别,因为它不是问题的一部分),所以对于这些我需要根据您的评论放入“p1”和“p2”? – 2012-03-18 16:26:51

0

以下内容将以最低的价格为您提供每件商品。您可以再次加入此项目,以获取剩余细节,加入项目和最低价格。如果价格相同,您需要选择一些类型的领带夹。这对你来说足够了吗?

SELECT COALESCE(instock.price, allItems.price) as lowest_price, item FROM 
(SELECT MIN(price) as minprice, item FROM products WHERE totalstock > 0 GROUP BY item) as instock 
RIGHT OUTER JOIN 
(SELECT MIN(price) as minprice, item FROM products GROUP BY item) as allItems 
ON instock.item = allItems.item 

编辑:MySQL没有完整的外连接。更改为正确的外部联接,并从缺货中删除该条件,以使其包含所有项目。

+0

谢谢,我现在试试。直到今天早上我都没有使用'join',我很模糊。我会尽力的! – 2012-03-18 14:41:32

+0

嗯,我得到一个SQL语法错误在您的代码中,试图将其添加到我的''select'如下:'SELECT * FROM products prod INNER JOIN(SELECT COALESCE(instock.price,outstock.price)as lowest_price,项目FROM(SELECT MIN(price)as minprice,item FROM WHERE totalstock> 0 GROUP BY item)as instock FULL OUTER JOIN(SELECT MIN(price)as minprice,item FROM products WHERE totalstock <= 0 GROUP BY item)as outstock ON instock.item = outstock.item)sortedProd ON sortedProd.item'我在'FULL OUTER JOIN'附近获得'语法错误'(' – 2012-03-18 14:52:37

+0

呃,mysql,我忘记了,没有完整的外连接,我将修复查询因为它 – Martijn 2012-03-18 16:21:10

相关问题