2014-03-06 38 views
2

我希望有人能帮助我。 我看了其他线程,但我无法找到正确的答案。使用MAX进行mysql查询

我有一个MySQL数据库具有以下数据:

id, company, datefrom, dateto, rate, point1, point2 

1, DHL, 2014-03-01, 2014-03-31, $1000, Paris, New York 

2, MRW, 2014-03-01, 2014-03-31, $1300, Paris, New York 

3, EXP, 2014-03-01, 2014-03-31, $1000, Paris, New York 

4, DHL, 2014-03-06, 2014-03-31, $900, Paris, New York 

5, FED, 2014-03-01, 2014-03-31, $1200, Paris, New York 

我需要做的地方,根据日期查询,这将只显示该日起有效的利率。 例如,如果今天是2014年3月6日,我需要的结果是:

2, MRW, 2014-03-01, 2014-03-31, $1300, Paris, New York 

3, EXP, 2014-03-01, 2014-03-31, $1000, Paris, New York 

4, DHL, 2014-03-06, 2014-03-31, $900, Paris, New York 

5, FED, 2014-03-01, 2014-03-31, $1200, Paris, New York 

正如你所看到的,记录1也不会显示为记录4替换记录1为2014年3月6日

我曾尝试以下查询,它的工作:

SELECT id, company, MAX(datefrom), dateto, rate, point1, point2 FROM mydatabase 
WHERE datefrom<='2014-03-06' and datefrom>='2014-03-06' 
AND point1='Paris' AND point2='New York' GROUP BY company, point1, point2 

这个查询只是它选择了所有企业的伟大工程,但对于DHL,它从记录1,但datefrom从记录4选择所有的领域!

我在做什么错?

+0

这个问题是问的每一天在SO(通常correctky回答),所以看看周围。 – Strawberry

+0

你在做什么错了 - 混合分组列与非选择组中。它在普通的SQL中无效。然而,MySQL允许这种行为,但在这种情况下可以自由选择任何行。您应该只选择将行分组为子查询,然后将结果与原始表结合起来 –

+0

完全正常 - 记录号4具有最新日期,因为MAX将从整个表中取最大值。所以你查询会在每一行中放入相同的值。 – Rolice

回答

1

使用MySQL的非标准分组支持:

SELECT * FROM (
    SELECT * FROM mydatabase 
    WHERE '2014-03-06' BETWEEN datefrom AND dateto 
    AND point1 = 'Paris' 
    AND point2 = 'New York' 
    ORDER BY datefrom DESC) x 
GROUP BY company 

该作品以第一顺序相匹配最新的启动行范围首先在内部查询,然后通过并非所有非聚合列编组, mysql为company的每个唯一值选择第一行行,第一行是您想要的行(先前已被排序)。

还要注意条件的改造使用BETWEEN这是更优雅。

+0

很好,谢谢波希米亚人,你的代码很棒。就是我以后的样子。只是一个问题,x做了什么? (在DESC末尾)x) – user1135218

+0

'x'是内部查询的* alias *,并且在从内部查询的结果中选择时需要指定别名,即使别名未被引用至。你可以使用任何你喜欢的名字,但是我喜欢使用'x',因为它简短而神秘 – Bohemian

0

您需要在当前记录datefrom之后添加不存在记录的条件与datefrom

select * from mydatabase t1 

WHERE '2014-03-06' between datefrom and dateto 
AND NOT EXISTS 
(
    select 1 from mydatabase 
    where company=t1.company 
    AND point1 = t1.point1 
    AND point2 = t1.point2 
    AND '2014-03-06' between datefrom and dateto 
    AND datefrom>t1.datefrom 
) 

SQLFiddle demo