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