我希望从两个表中获得某些产品的价格范围。
表1(产品):
pid | products_name | products_model
1 | Product 1.....| model 1
2 | Product 2.....| model 2
表2(products_prices):
pid | nerchant_id | price | sale_price | sale_start_date | sale_expire_date
1 | RVTBV | 11.90 | 0 | NULL | NULL
1 | QNUNU | 11.90 | 9.90 | 2013-05-01 | 2013-12-31
1 | YOLOR | 12.90 | 10.90 | 2013-04-01 | 2013-12-31
2 | RVTBV | 20.90 | 0 | NULL | NULL
2 | QNUNU | 29.90 | 25.90 | 2013-04-01 | 2013-12-31
2 | YOLOR | 29.90 | 0 | NULL | NULL
如何获得价格范围的结果如下:
pid | products_name | products_model | min_price | max_price
1 | Product 1.... | model 1 ...... | 10.90 ... | 12.90
2 | Product 2.... | model 2 ...... | 20.90 ... | 29.90
我使用主查询从table1获取产品数据,然后使用php foreach产品循环获取最小最大值,具体取决于销售开始和到期日期。
它完成了工作,但我不喜欢使用php的子查询。出于性能原因,我更喜欢一个MySQL查询。
感谢您的帮助。
直到现在,以下声明最好
SELECT p.pid,
p.manufacturers_id,
p.products_image,
p.products_name,
(select min(if(CURRENT_DATE BETWEEN pp.sale_start_date AND pp.sale_expire_date and pp.sale_price>'0', pp.sale_price, pp.price)) from products_prices pp where p.pid = pid) as min_price,
(select max(if(CURRENT_DATE BETWEEN pp.sale_start_date AND pp.sale_expire_date and pp.products_sale_price>'0', pp.sale_price, pp.price)) from products_prices pp where p.pid = pp.pid) as max_price
FROM products p
WHERE p.products_status = '1'
AND p.categories_id = '1'
ORDER BY min_price ASC LIMIT 0, 100
可以稍微优化一下吗?
恢复:
有时解决方案如此简单,以至于我看不到它;)
好的项目是价格比较平台。产品将每小时或类似更新,但并非所有价格都会发生变化。所以我们假设10%会更新。 但每次访问网站都必须检索数据。
在这种情况下,它会比写入更多(80-20)。
我可以在products表(min_price和max_price)中添加两个额外的列,如果price_data发生更改,我只会更新一次。
一方面,更新会有点复杂但不是戏剧性的。另一方面,数据将被快速检索。
我基于15000个产品测试3个选项来检索100行: 最差:approch组(超过1秒) 好:arheops的方法(0,12秒) 最好:用两个额外的柱子(0,07秒)更新一次
我选择了第三种选择。
感谢您的帮助!
答案 0 :(得分:0)
以下内容适用于您的要求。
<强>更新强>
现在,第一个查询还会考虑销售价格的start/end date
SELECT
p.pid,
p.products_name,
p.products_model,
pp.price as min_price,
pp.sale_price as max_price
FROM
products p
JOIN products_prices pp ON ( p.pid = pp.pid )
LEFT JOIN products_prices pp2 ON ( pp2.pid = pp.pid AND pp2.price > pp.price AND pp.sale_start_date BETWEEN pp2.sale_start_date AND pp2.sale_expire_date )
WHERE
pp2.pid IS NULL AND NOW() BETWEEN pp.sale_start_date and pp.sale_expire_date
以下内容获取max
的{{1}},min
可用产品
prices
答案 1 :(得分:0)
这取决于你的查询。
如果只查询产品中的某些值,这将是最佳的:
select pid,products_name,products_model,
(select min(price) from price where price.pid=product.pid) as min_price,
(select max(price) from price where price.pid=product.pid) as max_price
from product where some_filter_here;
如果你需要FULL表,这个是最好的:
select a.pid,products_name,products_model,min_price,max_price
from product as a
left join (
select pid,min(price) as min_price, max(price) as max_price
from price group by pid
) as b on b.pid=a.pid
答案 2 :(得分:0)
SELECT products.*,
MIN(IF(CURRENT_DATE BETWEEN sale_start_date AND sale_expire_date, sale_price, price)) min_price,
MAX(price) max_price
FROM products JOIN products_prices USING (pid)
GROUP BY pid
在sqlfiddle上查看。
答案 3 :(得分:0)
我想你实际上就是在这之后。如果没有销售,如果您要坚持在products_prices表中包含销售信息,我已将sale_price修改为NULL ...
DROP TABLE IF EXISTS products;
CREATE TABLE products
(pid INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,products_name VARCHAR(12) NOT NULL
,products_model VARCHAR(12) NOT NULL
);
INSERT INTO products VALUES
(1 ,'Product 1','model 1'),
(2 ,'Product 2','model 2');
DROP TABLE IF EXISTS products_prices;
CREATE TABLE products_prices
(pid INT NOT NULL
,merchant_id CHAR(5) NOT NULL
,price DECIMAL(5,2)NOT NULL
,sale_price DECIMAL(5,2) NULL
,sale_start_date DATE
,sale_expire_date DATE
,PRIMARY KEY(pid,merchant_id)
);
INSERT INTO products_prices VALUES
(1,'RVTBV',11.90,NULL,NULL,NULL),
(1,'QNUNU',11.90,9.90,'2013-05-01','2013-12-31'),
(1,'YOLOR',12.90,10.90,'2013-04-01','2013-12-31'),
(2,'RVTBV',20.90,NULL,NULL,NULL),
(2,'QNUNU',29.90,25.90,'2013-04-01','2013-12-31'),
(2,'YOLOR',29.90,NULL,NULL,NULL);
SELECT p.*
, MIN(CASE WHEN CURDATE() BETWEEN sale_start_date AND sale_expire_date THEN pp.sale_price ELSE pp.price END) min_price
, MAX(CASE WHEN CURDATE() BETWEEN sale_start_date AND sale_expire_date THEN pp.sale_price ELSE pp.price END) max_price
FROM products p
JOIN products_prices pp
ON pp.pid = p.pid
GROUP
BY p.pid;
+-----+---------------+----------------+-----------+-----------+
| pid | products_name | products_model | min_price | max_price |
+-----+---------------+----------------+-----------+-----------+
| 1 | Product 1 | model 1 | 10.90 | 11.90 |
| 2 | Product 2 | model 2 | 20.90 | 29.90 |
+-----+---------------+----------------+-----------+-----------+