2012-08-22 100 views
1

我有存储车企与像一个结构的最后N条记录:MySQL的 - 选择基于列

+-----------------+--------------+------+-----+---------+----------------+ 
| Field   | Type   | Null | Key | Default | Extra   | 
+-----------------+--------------+------+-----+---------+----------------+ 
| id    | int(11)  | NO | PRI | NULL | auto_increment | 
| model   | varchar(255) | YES |  | NULL |    | 
| make   | varchar(255) | YES |  | NULL |    | 
| year   | varchar(255) | YES |  | NULL |    | 
| avg_price  | decimal(8,2) | YES |  | NULL |    | 
| median_price | decimal(8,2) | YES |  | NULL |    | 
| created_at  | datetime  | YES |  | NULL |    | 
| updated_at  | datetime  | YES |  | NULL |    | 
+-----------------+--------------+------+-----+---------+----------------+ 

的数据,某一年可能会在不同的时间插入。

For example model 'Honda', make 'Accord' might have results like: 
+------+-----------+--------------+--------+---------------------+ 
| year | avg_price | median_price | model | created_at   | 
+------+-----------+--------------+--------+---------------------+ 
| 1992 | 2431.29 |  2000.00 | accord | 2012-02-23 17:31:41 | 
| 1993 | 2609.13 |  2195.00 | accord | 2012-02-23 17:31:44 | 
| 1994 | 2858.81 |  2400.00 | accord | 2012-02-23 17:31:44 | 
| 2000 | 4771.99 |  4450.00 | accord | 2012-02-23 17:31:46 | 
| 2001 | 5260.16 |  5000.00 | accord | 2012-02-23 17:31:46 | 
| 2000 | 4860.19 |  4795.00 | accord | 2012-08-15 06:09:52 | 
| 2001 | 5071.49 |  4990.00 | accord | 2012-08-15 06:09:52 | 
| 2002 | 5872.80 |  5795.00 | accord | 2012-08-15 06:09:52 | 
| 2003 | 7521.44 |  7950.00 | accord | 2012-08-15 06:09:52 | 
| 2004 | 8348.19 |  8495.00 | accord | 2012-08-15 06:09:52 | 

我想检索所有本田雅阁数据,这是汽车制造当年最新的。

所以在上面的例子中,我想从2012-08-15 06:09:52检索数据多年的2000,2001,2002,2003,2004 ,但较大的年份将从2012年 - 02-23 17时31分41秒

select year,avg_price,median_price,model,created_at 
from car_prices 
where make='honda' and model= 'accord' group by year asc 

上面的查询得到插入每一年每一年不同的数据,但不是最后一个记录。

任何想法如何获得每年以及最新的独特数据?

回答

1

对于性能和guarnanteed行为,你应该创建一个查找并加入上。

在您的情况下,您想要查找任何给定make, model, year组的最新created_at值。下面的代码中的子查询是这样做的。

然后您再次加入您的原始数据,只找到那些具有那些make, model, year, created_at值的记录。

这确实意味着它有多个记录与make, model, year, created_at相同的值,您会得到多个make, model, year的结果。

确保您有一个包含(make, model, year, created_at)的索引,以便快速搜索最近的created_at以及加入。

SELECT 
    * 
FROM 
    car_prices 
INNER JOIN 
(
    SELECT 
    make, model, year, MAX(created_at) as created_at 
    FROM 
    car_prices 
    GROUP BY 
    make, model, year 
) 
    AS most_recent 
    ON car_prices.make  = most_recent.make 
    AND car_prices.model  = most_recent.model 
    AND car_prices.year  = most_recent.year 
    AND car_prices.created_at = most_recent.created_at 
WHERE 
     most_recent.make = 'honda' 
    AND most_recent.model = 'accord' 
1
select * from(
select year,avg_price,median_price,model,created_at 
from car_prices 
where make='honda' and model= 'accord'  
order by created_at desc,year desc) m 
group by year asc 
+0

不,那是行不通的。即使在我更正了您通过切换组输入的sql后修改了 – truthSeekr

+1

修改。请尝试。你可以尝试子查询。 – sel

+0

整洁。很棒。非常感谢你 – truthSeekr

2
SELECT p.* 
FROM car_prices p 
JOIN (SELECT year, MAX(created_at) latest 
     FROM car_prices 
     WHERE make = 'honda' AND model = 'accord' 
     GROUP BY year) mp 
ON p.year = mp.year AND p.created_at = mp.latest 
WHERE p.make = 'honda' AND p.model = 'accord' 
0

添加一个默认设置为0的新布尔列。我用:is_old

| is_old   | TINYINT(1) | NO |  | 0 |    | 

当插入价格为新的品牌,型号,年份,我首先做:

UPDATE car_prices 
    SET `is_old`=1 
WHERE 
    `make`='make_to_insert' AND 
    `model`='model_to_insert' AND 
    `year`='year_to_insert'; 

然后我插入新行。

为了得到最近的价格是非常简单:

SELECT * FROM car_prices 
WHERE `is_old` = 0; 

而且你的查询示例将是:

SELECT * FROM 
    car_prices 
WHERE 
     make = 'honda' 
    AND model = 'accord' 
    AND is_old = 0;