如何通过日期和模型年过滤此MySQL查询?

时间:2013-01-06 16:36:56

标签: mysql

我有一张桌子,它看起来像这样:

id  year    effective   price
1   2000    2012-01-01  1000
2   2001    2012-01-01  1100
3   2002    2012-01-01  1200
4   2003    2012-01-01  1300
5   2000    2012-03-01  1500
6   2001    2012-03-01  1600
7   2002    2012-03-01  1700
8   2003    2012-03-01  1800
9   2000    2011-12-01  900
10  2001    2011-12-01  1000
11  2002    2011-12-01  1100
12  2003    2011-12-01  1200

在此表中包含大量数据,其中包含许多项目的价格历史记录。它们不是任何常规顺序,似乎人们随机进入数据库并进行了更改。我没有设置这个数据库,也没有开发插入和更新数据的应用程序。我唯一的目标是以客户想要的方式呈现指定的数据。

话虽如此,我很难获得所需的信息。在上面的示例数据中,我需要能够对每个特定年份的价格进行排序并获得不同的数字。这必须按最终用户输入的最近生效日期进行过滤。

例如,如果用户想要最新的数据(截至今天的日期),响应应该是这样的:

5   2000    2012-03-01  1500
6   2001    2012-03-01  1600
7   2002    2012-03-01  1700
8   2003    2012-03-01  1800

如果用户另一方面想要截至2012-02-01的最新数据,那么它应该返回:

1   2000    2012-01-01  1000
2   2001    2012-01-01  1100
3   2002    2012-01-01  1200
4   2003    2012-01-01  1300

我的问题在于不知道如何构建此查询。甚至可以将其构建为单个查询,还是必须执行多个查询才能获取数据?我希望尽可能减少占地面积,因为我必须从四个不同的表中获取数据,这些表共享多年,但有其他不同的数据。

我尝试过此查询无效:

select id, year, effective, price
from mytable
group by year
having effective < '2012-02-01'

给出了这个结果:

1   2000    2012-01-01  1000
2   2001    2012-01-01  1100
3   2002    2012-01-01  1200
4   2003    2012-01-01  1300

我原本以为这会给我正确的信息,因为它似乎是合乎逻辑的。

我尝试了这个查询,也没有效果:

select distinct year, id, effective, price
from mytable
group by effective
having effective < '2012-02-01'

返回此结果:

1   2000    2012-01-01  1000
5   2000    2012-03-01  1500
9   2000    2011-12-01  900

此查询似乎完全错误。

有关如何正确执行查询的任何建议吗?

1 个答案:

答案 0 :(得分:2)

如果过滤子查询中的日期,则使用相关子查询获取MAX(effective)year并加入主表将起作用。这个想法是子查询将返回模型年和生效日期的集合,这些日期是最小日期,小于您在WHERE子句中指定的日期。这些返回的列可以连接回主表以拉入其余列。

SELECT 
  mytable.*
FROM
  mytable
  JOIN (
     /* Join on a subquery which returns the greatest date per year */
     SELECT MAX(effective) as effective, year
     FROM mytable 
     /* Filtering on some date in the subquery WHERE clause... */
     WHERE effective < '2012-01-01'
     GROUP BY year
  /* Since the subquery returns effective,year, join on both those cols against the main table */
  ) maxd ON mytable.effective = maxd.effective AND mytable.year = maxd.year

示例有效2012-01-01:http://sqlfiddle.com/#!2/05546/4

示例有效2013-01-01:http://sqlfiddle.com/#!2/05546/5