0

我想从两张表中获取某些产品的价格范围。

表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)。

我可以在产品表中添加两个额外的列(min_price 和 max_price),如果 price_data 发生变化,我只更新一次。

一方面,更新会稍微复杂一些,但这不是戏剧。另一方面,数据将被非常快速地检索。

我有基于 15000 个产品的 testet 3 选项来检索 100 行:最差:按方法分组(超过 1 秒)好:arheops 的方法(0,12 秒)最好:用两个额外的列更新一次(0,07 秒)

我选择第三个选项。

还是要谢谢你的帮助!

4

4 回答 4

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上查看。

于 2013-04-20T09:53:57.577 回答
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可用的 ,minprices

SELECT
  p.pid,
  p.products_name,
  p.products_model,
  MIN( LEAST( pp.price, pp.sale_price) ) as min_price,
  MAX( GREATEST( pp.price, pp.sale_price) ) as max_price
FROM
  products p
  JOIN products_prices pp ON ( p.pid = pp.pid )
WHERE
  pp.sale_price <> 0
GROUP BY
  p.pid

SQLFIDDLE

于 2013-04-20T09:09:42.530 回答
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
于 2013-04-20T09:12:05.990 回答
0

我想你实际上是在追求这个。如果没有销售,我已将 sale_price 修改为 NULL,如果您要坚持在 products_prices 表中包含销售信息,那应该是这样......

 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 |
+-----+---------------+----------------+-----------+-----------+
于 2013-04-20T12:12:12.427 回答