mysql在多个表中获取最大最小值

时间:2013-04-20 08:57:14

标签: php mysql

我希望从两个表中获得某些产品的价格范围。

表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秒)更新一次

我选择了第三种选择。

感谢您的帮助!

4 个答案:

答案 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

SQLFIDDLE

答案 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 |
+-----+---------------+----------------+-----------+-----------+
相关问题