MySql检索产品和价格

时间:2013-06-07 08:28:30

标签: mysql database database-design

我想检索所有产品的清单,以及给定期间的相关价格。

产品表:

Id
Name
Description

价格表:

Id 
Product_id
Name
Amount
Start
End
Duration

最重要的是,产品可以具有多种价格,即使在同一时期,但持续时间不同。 例如,“2013-06-01 - > 2013-06-08”的价格和“2013-06-01 - > 2013-06-05”的另一个价格

因此,我的目标是在一定时期内检索所有产品的清单,例如10个产品的分页,加入到期间存在的价格。

这样做的基本方法是:

SElECT *
FROM product
LEFT JOIN prices ON ...
WHERE prices.start >= XXX And prices.end <= YYY
LIMIT 0,10

使用这个简单的解决方案时的问题是,我不能仅检索10个产品,而是检索10个产品*价格,这在我的情况下是不可接受的。

所以解决方案是:

SElECT *
FROM product
LEFT JOIN prices ON ...
WHERE prices.start >= XXX And prices.end <= YYY
GROUP BY product.id
LIMIT 0,10

但问题是,我只会为每种产品检索“1”价格。

所以我想知道处理这个问题的最佳方法是什么。 我可以例如使用组函数,例如“group_concat”,并在字段中检索字符串中的所有价格,例如“200/300/100”等等。这似乎很奇怪,并且需要在服务器语言方面工作才能转换为可读信息,但它可以工作。

另一个解决方案是为每个价格使用不同的列,具体取决于持续时间:

SELECT 
   IF( NOT ISNULL(price.start) AND price.duration = 1, price.amount , NULL) AS price_1_day
   ---- same here for all possible durations ---
From ...

我猜也好(我不确定这是否可行),但我可能需要创建大约250列以涵盖所有可能性。 这是一个安全的选择吗?

非常感谢任何帮助

2 个答案:

答案 0 :(得分:1)

我相信group_concat将是最好的前进方式,因为它的目的是聚合与特定列相关的多个数据。

但是,如果使用用户定义的变量,则可以在peterm的SQL小提琴中进行调整,这可以在1个查询中进行。 (如果忽略了设置变量的初始查询)

http://dev.mysql.com/doc/refman/5.7/en/user-variables.html

SET @productTemp := '', @increment := 0;

SElECT
  @increment := if(@productTemp != Product_id, @increment + 1, @increment) AS limiter,
  @productTemp :=Product_id as Product_id,
  Product.name,
  Price.id as Price_id,
  Price.start,
  Price.end
FROM 
  Product
LEFT JOIN
  Price ON Product.Id=Price.Product_id
WHERE 
  `start` >= '2013-05-01' AND `end` <= '2013-05-15'
GROUP BY
 Price_id
HAVING 
  limiter <=2

我们在这里做的只是在产品ID与遇到的最后一个产品ID不同时才增加用户定义的var“incrementmenter”。

由于别名不能在WHERE条件中使用,我们必须通过唯一ID(在这种情况下为价格ID)进行GROUP,以便我们可以使用HAVING减少结果。在这种情况下,我有一个完整的结果集,应包括3个产品ID,减少到仅显示2。

请注意:这不是我建议在大型数据集或生产环境中使用的解决方案。即使是mysql手册也强调了用户定义的变量可能会有些不规律,具体取决于优化程序采用的路径。但是,我过去曾使用它们对一些内部统计数据产生了很大影响。

小提琴:http://sqlfiddle.com/#!2/96c92/3

答案 1 :(得分:0)

没有样本数据和所需的输出很难说,但你可以试试这样的东西

SElECT p.*, q2.*
  FROM 
(
  SElECT Product_id
    FROM Price
   WHERE `start` >= '2013-05-01' AND `end` <= '2013-05-15'
   GROUP BY Product_id
  LIMIT 0,10
) q1 JOIN 
(
    SELECT *
      FROM Price
     WHERE `start` >= '2013-05-01' AND `end` <= '2013-05-15'
) q2 ON q1.Product_id = q2.Product_id JOIN product p
     ON q1.Product_id = p.Id

这是 SQLFiddle 演示