【问题标题】:SQL join several tables based on latest entry in transaction table per join recordSQL 根据每个连接记录的事务表中的最新条目连接多个表
【发布时间】:2014-06-27 21:02:21
【问题描述】:

我有一个带有时间戳的事务表

  • 一笔交易有一个事件和一个用户。
  • 所有交易都有一个事件,
  • 所有事件至少有一个事务,
  • 每个事务都有一个必须存在的用户,
  • 用户不一定有交易。

输出将是一种 evt 列表
输出行数应等于 db.evt 记录数。

每个表的第一列是 Autoinc 唯一索引。
在事务中,这些是其他表的 fks。

问题是我需要事务表中 evt 的最新时间戳的事务。

我对 SQL(使用 MySQL)还是比较陌生,虽然我在连接方面感到困惑。我不知道如何通过时间戳获取 evID 的最新记录。

我查看了有关该主题的其他问题,但没有找到解决我的问题。 (当然,仅加入就有 14K,所以我可能错过了一个)

示例表数据如下: 表结构希望很明显,如果需要,我会对其进行编辑。

编辑: 为了清楚起见,我更改了表和列的名称(并避免匹配关键字)

我在下面尝试了 Stuart 的回答,但出现错误:

答案:

SELECT
  eventTable.EvtName AS EvtD,
  transTable.TranAct AS LastTrans,
  userTable.UserName AS UsrNm
FROM
  transTables,
  INNER JOIN (
    SELECT evtID, MAX(TransID) TransID FROM transTable GROUP BY evtID 
  ) last ON last.evtID = transTable.evtID AND last.TransID = transTable.TransID
  INNER JOIN eventTable ON eventTable.evtID = transTable.evtID
  INNER JOIN userTable ON userTable.usId = transTable.usId

回复:

#1064 - You have an error in your SQL syntax; 
    check the manual that corresponds to your MySQL server version for the right syntax to use near
     'INNER JOIN (
        SELECT evtID, MAX(TransID) TransID FROM transTable GROUP BY evt' 
    at line 7 

表格:

db.transTable

| TransID | EvtID | TranAct   | timestamp               | UserID
----------------------------------------------------------------
|  1      |  1    |  add      | 2014-05-08 08:10:00.000 | 3
|  2      |  2    |  add      | 2014-05-08 09:10:00.000 | 2
|  3      |  3    |  add      | 2014-05-08 10:10:00.000 | 3
|  4      |  2    |  validate | 2014-05-08 11:10:00.000 | 5
|  5      |  3    |  validate | 2014-05-08 12:10:00.000 | 3
|  6      |  2    |  reverse  | 2014-05-08 13:10:00.000 | 1
|  7      |  1    |  edit     | 2014-05-08 14:10:00.000 | 4
|  8      |  4    |  add      | 2014-05-08 15:10:00.000 | 3
|  9      |  5    |  add      | 2014-05-08 16:10:00.000 | 2


db.eventTable

| EvtID | EvtName 
-----------------
|  1    |  Evt1
|  2    |  Evt2
|  3    |  Evt3
|  4    |  Evt4
|  5    |  Evt5


db.userTable

| UserID | UserName 
--------------------
|  1     |  Usr1      
|  2     |  Usr2      
|  3     |  Usr3      
|  4     |  Usr4      
|  5     |  Usr5      

期望的输出:

eventTable.EvtName AS EvtD
transTable.TranAct AS LastTrans
userTable.UserName AS UsrNm

| EvtD | LastTrans | UsrNm
--------------------------
| Evt1 | edit      | Usr4
| Evt2 | reverse   | Usr1
| Evt3 | validate  | Usr3
| Evt4 | add       | Usr3
| Evt5 | add       | Usr2

非常感谢您的帮助。

【问题讨论】:

  • 对不起。我误解了。我已经为你修复了@StuartIngram 的答案。
  • @eggyal 深表感谢。我什至没有注意到逗号,因为我一直在看 Inner Join 本身。我将重新阅读您的链接,因为它确实有助于缩小其他一些问题。再次感谢您

标签: mysql sql join timestamp


【解决方案1】:

类似这样的工作应该使用派生表来消除所有事务,除了每个 evId 的最新事务。

SELECT
  eventTable.EvtName AS EvtD,
  transTable.TranAct AS LastTrans,
  userTable.UserName AS UsrNm,
FROM
  transTable
  INNER JOIN (
    SELECT evId, MAX(UID) uid FROM transTable GROUP BY evId 
  ) last ON last.evId = transTable.evId AND last.uid = transTable.uid
  INNER JOIN eventTable ON eventTable.evId = transTable.evId
  INNER JOIN userTable ON userTable.usId = transTable.usId

【讨论】:

  • @Stuart Ingram 我尝试了答案并得到了错误。我对其进行了调整,但没有进一步的进展。当我将 Inner Join 本身作为一个选择取出时,它工作正常。
  • Andrei,如果您取出子选择,查询将报告所有交易,而不仅仅是每个事件类型的最后一个。您使用的是什么 SQL 数据库,特别是您遇到了什么错误?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 2019-01-17
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
  • 2014-11-03
  • 2023-01-15
相关资源
最近更新 更多