Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySql检索产品和价格_Mysql_Database_Database Design - Fatal编程技术网

MySql检索产品和价格

MySql检索产品和价格,mysql,database,database-design,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个产品为例,与该时间段

我想检索所有产品的列表,以及它们在给定时期内的相关价格

产品表:

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
SElECT *
FROM product
LEFT JOIN prices ON ...
WHERE prices.start >= XXX And prices.end <= YYY
GROUP BY product.id
LIMIT 0,10
Thta也会起作用,我想我不确定这是否可行,但是我可能需要创建大约250列来涵盖所有可能性。这是一个安全的选择吗


如果没有样本数据和所需的输出,很难判断是否有帮助,但您可以尝试以下方法

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

这里是演示

我认为,小组讨论是解决这一问题的最佳方式,因为它的目的是聚合与特定列相关的多个数据段

然而,根据peterm的SQL FIDLE,如果使用用户定义的变量,这可以在1个查询中完成。如果忽略设置变量的初始查询

我们在这里所做的只是在产品id与上次遇到的产品id不相同时增加用户定义的var incrementer

由于别名不能在WHERE条件下使用,因此在本例中,我们必须按唯一ID price ID进行分组,以便使用have减少结果。在本例中,我有一个完整的结果集,应该包括3个产品ID,减少到只显示2个

请注意:这不是我在大型数据集或生产环境中推荐的解决方案。甚至mysql手册也强调指出,用户定义的变量的行为可能有些不稳定,这取决于优化器采用的路径。然而,我在过去的一些内部统计数据中使用了它们


Fiddle:

由于您仅限于10种产品,因此您有两种选择:如您所说使用GROUP_CONCAT,或者有两个查询,一个查询产品,一个查询价格,并将数据加入客户端。第二个将为您提供更大的灵活性如果使用group concat,请记住默认长度限制为1024个字符。这不应该是个问题,除非你有很多价格。如果需要,可以通过group_concat_max_len系统变量进行更改。您想要10个产品的记录或每个产品最多10个记录,我对您的方法有点困惑。我想要10个第一个产品记录,以及所有相关的价格。把我的帖子编辑得有点清楚我也考虑过这个解决方案,但是用两个等价的查询来检索相同的元素不是太过分了吗?MySql是否能很好地处理这个问题,比如重用某种缓存?我的最终查询要复杂得多价格部分下有很多连接和条件,两次启动此请求可能会花费我数百毫秒。顺便说一句,我还想到了从产品中选择*从产品中选择id从产品左连接价格中选择id,但我也确实不确定性能,因为WHERE-in-part中的查询肯定会尝试扫描所有rows@elwood这当然需要更多的工作,但你的要求也是如此。但要确定这一点,必须在真实数据上进行测试。如果您为所有联接和筛选条件设置了所有索引,那么IMHO应该可以正常工作。@elwood这种方法不会给出您要求的结果,因为Product table中的前10个产品可能没有所需时间间隔的价格。所以你必须从价格表中选择它们。@elwood这个答案有用吗?你的问题需要更多的帮助吗?
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
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