简体   繁体   English

如何通过MySQL查询从联接表中检索最低价格

[英]How to retrieve min price via mysql query from a joined table

I have two tables 我有两张桌子

Products
id, name, last_updated
1, Computer table,  2014-07-20 09:00:00
2, Fruits basket,  2014-07-21 09:00:00
3, Hard Disk,  2014-07-22 09:00:00


Products_prices
id, product_id, min_price, max_price, description
1, 1, 10.00, 20.00, glass top
2, 1, 40.00, 80.00, hard wood
3, 1, 5.00, 10.00, pvc
4, 2, 15.00, 30.00, Mangoes only
5, 3, 30.00, 60.00, 1 TB
6, 3, 45.00, 90.00, 2 TB
7, 3, 20.00, 40.00, 500 GB

I need to retrieve information as below 我需要检索以下信息

product.id, product.name, product_prices.min_price, product_prices.max_price, price_diff_percentage ( calculated as round((max_price-min_price)/max_price*100) )

If I do a LEFT JOIN eg 如果我做一个左联接,例如

SELECT *, round((max_price-min_price)/max_price*100) price_diff_pct 
FROM products p LEFT JOIN Product_prices pp on pp.product_id = p.id 

Then I get list of product with all the product prices rows eg 然后我得到所有产品价格行的产品清单,例如

1, computer table, 10.00, 20.00, 50, glass top
1, computer table, 40.00, 80.00, 50, hard wood
1, computer table, 5.00, 10.00, 50, pvc
2, fruits basket, 15.00, 30.00, mangoes only
3, hard disk, 30.00, 60.00, 50 1 TB
3, hard disk, 45.00, 90.00, 50 2 TB
3, hard disk, 20.00, 40.00, 50 500 GB

What I want it be changed to is to return one product row with lowest min price and the price_diff_pct eg instead of the above return set it returns the below 我想要将其更改为以最低价格和price_diff_pct返回一个产品行,例如,而不是上面的返回集,它返回下面的

1, computer table, 5.00, 10.00, 50, pvc
2, fruits basket, 15.00, 30.00, mangoes only
3, hard disk, 20.00, 40.00, 50 500 GB

And I need to order by the last_updated date. 我需要在last_updated日期之前订购。

How do I go about this? 我该怎么办?

UPDATE: 更新:

create table products   (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(300) NOT NULL,
  `last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`)
);
INSERT INTO products (1, 'Computer table',  '2014-07-20 09:00:00');
INSERT INTO products (2, 'Fruits basket',  '2014-07-21 09:00:00');
INSERT INTO products (3, 'Hard Disk',  '2014-07-22 09:00:00');


CREATE TABLE IF NOT EXISTS `product_prices` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `product_id` int(10) unsigned NOT NULL,
  `min_price` float(10,2) NOT NULL,
  `max_price` float(10,2) NOT NULL,
  `description` varchar(300) NOT NULL,
  PRIMARY KEY (`id`)
);
INSERT INTO product_prices (1, 1, '10.00', '20.00', 'glass top');
INSERT INTO product_prices (2, 1, '40.00', '80.00', 'hard wood');
INSERT INTO product_prices (3, 1, '5.00', '10.00', 'pvc');
INSERT INTO product_prices (4, 2, '15.00', '30.00', 'Mangoes only');
INSERT INTO product_prices (5, 3, '30.00', '60.00', '1 TB');
INSERT INTO product_prices (6, 3, '45.00', '90.00', '2 TB');
INSERT INTO product_prices (7, 3, '20.00', '40.00', '500 GB');

Use a sub query to get the lowest min_price for each product and join that against product price to get the rest of the details for that product pice. 使用子查询获取每种产品的最低min_price,然后将其与产品价格相结合以获取该产品价格的其余详细信息。

Assuming that min_price is unique for a product:- 假设min_price对于产品是唯一的:

SELECT p.*, pp.*, ROUND((pp.max_price-pp.min_price)/pp.max_price*100) AS price_diff_pct 
FROM products p 
LEFT OUTER JOIN
(
    SELECT product_id, MIN(min_price) AS min_min_price
    FROM Products_Prices
    GROUP BY product_id
) sub0
ON sub0.product_id = p.id 
LEFT JOIN Product_prices pp 
ON pp.product_id = sub0.product_id
AND pp.min_price = sub0.min_min_price

EDIT 编辑

If you want to avoid a sub query you could probably do this using 2 LEFT OUTER JOINs. 如果要避免子查询,则可以使用2个LEFT OUTER JOINs来执行。

This gets the products, joins that to product prices and then joins again to product prices where the 2nd product prices is less than the first, then uses the WHERE clause to exclude any where a 2nd price is found (ie, checks the 2nd price is null). 这将获得产品,将其加入产品价格,然后再次加入第二个产品价格小于第一个产品价格的产品价格,然后使用WHERE子句排除找到第二个价格的任何产品(即,检查第二个价格为空值)。

SELECT p.*, pp1.*, ROUND((pp1.max_price-pp1.min_price)/pp1.max_price*100) AS price_diff_pct 
FROM products p 
LEFT OUTER JOIN Products_Prices pp1
ON pp1.product_id = p.id 
LEFT OUTER JOIN Products_Prices pp2
ON pp2.product_id = pp1.product_id
AND pp2.min_price < pp1.min_price
WHERE pp2.product_id IS NULL

You can use another field (is_active ) for table Products_prices. 您可以将另一个字段(is_active)用于表Products_prices。 When you insert a new row then make is_active = 'N' and you can make change in your join query accordingly. 当您插入新行时,请使is_active ='N',然后可以在连接查询中进行相应的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM