【问题标题】:MySQL join two table with the maximum value on another fieldMySQL将两个表与另一个字段的最大值连接起来
【发布时间】:2013-09-26 13:31:07
【问题描述】:

我有两个表账户和余额

/---------------------\
| cid | name | mobile |
|---------------------|
|  1  | ABC  | 12345  |
|---------------------|
|  2  | XYZ  | 98475  |
\---------------------/

/----------------------------\
| date       | cid | balance |
|----------------------------|
| 2013-09-19 |  1  |   5000  |
|----------------------------|
| 2013-09-19 |  2  |   7000  |
|----------------------------|
| 2013-09-20 |  1  |    300  |
|----------------------------|
| 2013-09-20 |  2  |   4500  |
|----------------------------|
| 2013-09-21 |  2  |    600  |
\----------------------------/

我想加入这两个表并获取特定 cid 的最大日期的余额。

输出结果为 -

/--------------------------------------------\
| cid | name | mobile | date       | balance |
|--------------------------------------------|
|  1  | ABC  | 12345  | 2013-09-20 |   300   |
|--------------------------------------------|
|  2  | XYZ  | 98475  | 2013-09-21 |   600   |
\--------------------------------------------/

【问题讨论】:

    标签: mysql sql view max


    【解决方案1】:

    你需要像这样使用两个子查询:

    SELECT a.cid, a.name, a.mobile, b.date, b.balance
    FROM account a 
    JOIN
    (
        SELECT b1.* FROM balance b1
        JOIN
        (
          SELECT cid, MAX(Date) As maxDate
          FROM balance
          GROUP BY cid
        ) b2
        ON b1.cid = b2.cid
        AND b1.date = b2.maxDate
    ) b
    ON a.cid = b.cid;
    

    输出:

    CID NAME MOBILE DATE BALANCE
    1 ABC 12345 September, 20 2013 00:00:00+0000 300
    2 XYZ 98475 September, 21 2013 00:00:00+0000 600

    看到这个SQLFiddle

    编辑

    正如 cmets 中所讨论的,这个查询也可以只用一个子查询来编写:

    SELECT a.cid, a.name, a.mobile, b1.date, b1.balance 
    FROM account a 
    JOIN balance b1 ON a.cid = b1.cid     
    JOIN (
        SELECT cid, MAX(Date) As maxDate 
        FROM balance 
        GROUP BY cid
    ) b2 
    ON b1.cid = b2.cid 
    AND b1.date = b2.maxDate
    

    查看调整后的SQLFiddle

    【讨论】:

    • 谢谢@hims056 我得到了我想要的结果,但它不能保存为视图。当我尝试另存为视图时,我收到一条错误消息,因为 -1349-View 的 SELECT 在 from 子句中包含一个子查询。请帮助我。我需要将此查询保存在 VIEW 中。
    • @newcomer - 视图不能包含子查询。但是,您可以为上述每个子查询创建视图,然后在最终视图中使用这些视图。 See some tips here.
    • 谢谢你,真的!
    • 非常感谢。被困在类似的场景一个多小时
    • @HimanshuJansari:对不起,我知道你很久以前就回答了这个问题,但我遇到了类似的问题,你的回答帮助我建立了查询。由于复制粘贴错误,我想出了这个解决方案:SELECT a.cid, a.name, a.mobile, b1.date, b1.balance FROM account a JOIN balance b1 ON a.cid = b1.cid JOIN (SELECT cid, MAX(Date) As maxDate FROM balance GROUP BY cid) b2 ON b1.cid = b2.cid AND b1.date = b2.maxDate。我来回测试它,得到相同的结果,只是想知道,为什么你的答案更好?谢谢
    【解决方案2】:
    SELECT a.cid, a.name, a.mobile, MAX(b.date), b.balance 
    FROM account AS a
    INNER JOIN balance AS b
    WHERE a.cid=b.cid 
    GROUP BY cid;
    

    抱歉,我没有注意到第三张表中的余额列。

    SELECT a.cid, a.name, a.mobile, b.date, b.balance 
    FROM account AS a
    INNER JOIN (
          SELECT c.date, c.cid, c.balance FROM balance AS c
          INNER JOIN (
                SELECT cid AS cid2, MAX(date) AS date2
                FROM balance
                GROUP BY cid2) AS d
    ON c.cid=d.cid2 
    AND c.date=d.date2
    ) AS b
    ON a.cid=b.cid 
    GROUP BY cid;--
    

    【讨论】:

    • 你好 Leo,使用聚合函数而不分组 每个 字段将为这些字段提供random values
    【解决方案3】:

    以下语句应该会为您提供所需的结果:

    SELECT cid, name, mobile, MAX(date), blance  
    FROM account
    LEFT JOIN balance
    ON account.cid = balance.cid
    GROUP BY balance.cid
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      相关资源
      最近更新 更多