【问题标题】:SQL return transaction table with the date of previous paymentSQL 返回交易表与上次付款日期
【发布时间】:2011-06-21 22:19:00
【问题描述】:

我在 Access 中有一个查询,它返回所有客户的交易 字段是

TransID、TenantID、TransactionType、Amount、TransactionDate

其中 TransactionType =1 表示费用,2 表示付款

我想返回此查询的所有记录,其中包含一个额外字段,其中包含此客户 (TenantID) 的上一次付款的 (TransactionType =2) TransactionDate 如果没有以前的付款,我只想返回 null 作为上一个交易日期的记录。

你能帮帮我吗?

【问题讨论】:

  • 您如何从数据字段中定义“以前的付款”?如果同一天有不止一笔付款怎么办?您的 TransactionDate 字段是否还包含非零时间组件?如果是这样,为什么它的名字暗示它没有时间成分?

标签: sql ms-access greatest-n-per-group


【解决方案1】:

使用子查询,传入外部查询的交易日期:

SELECT TransID, TenantID, TransactionType, Amount, TransactionDate,
       (SELECT MAX(I.TransactionDate)
        FROM unnamed_table I
        WHERE I.TransactionDate < O.TransactionDate
          AND I.TransactionType = 2
          AND I.TenantID = O.TenantID) PrevTransDate
FROM unnamed_table O

【讨论】:

  • SELECT I.TransactionType 替换为SELECT MAX(I.TransactionDate) 并将AND I.TransactionType = 2 AND I.TenantID = O.TenantID 添加到内部查询的WHERE 子句中?
【解决方案2】:
select t1.TransID, t1.TenantID, t1.TransactionType, t1.Amount, t1.TransactionDate,  max(t2.TransactionDate)
from table as t1 left outer join table as t2 on (t1.TenantID=t2.TenantID)
Where t1.TransactionType =1 and t2.TransactionType =2
and t1.TransactionDate > t2.TransactionDate

【讨论】:

  • Access 是否需要 GROUP BY 子句才能允许使用 MAX()?
【解决方案3】:

您需要一个子查询,或者您需要使用 MAX 和字符串函数做一些魔术,以便在一个查询中做得比这更好,或者您需要一个唯一标识前一个事务的 id。

select t.*, MAX(prevt.transid) as prev_trans_id
from transactions t 
left join transactions prevt
on t.tenantid=prevt.tenantid 
and t.transid > prevt.transid
group by t.transid

【讨论】:

  • 基本上你需要在查询中加入表两次。前一笔交易一次。并且它需要是一个外部左连接,因为可能没有以前的事务。
  • 您的查询中的pt 是什么? prevt 别名的错字?我不知道这是如何到达 previous 事务的——它只是由租户将表连接到自身...
【解决方案4】:

另一种方法:

SELECT
    T1.TransID,
    T1.TenantID,
    T1.TransactionType,
    T1.Amount,
    T1.TransactionDate,
    T2.TransactionDate AS PreviousPaymentDate
FROM
    Transactions T1
LEFT OUTER JOIN Transactions T2 ON
    T2.TenantID = T1.TenantID AND
    T2.TransactionType = 2 AND
    T2.TransactionDate < T1.TransactionDate
LEFT OUTER JOIN Transactions T3 ON
    T3.TenantID = T1.TenantID AND
    T3.TransactionType = 2 AND
    T3.TransactionDate < T1.TransactionDate AND
    T3.TransactionDate > T2.TransactionDate
WHERE
    T3.TransID IS NULL AND
    <your normal selection criteria>

您基本上得到的是同一租户的类型 2 的最后一笔交易 (T2),而该租户和同一类型 2 的其他交易在该交易之后没有出现(这就是 T3.TransID IS NULL 所做的 -它将为 NULL 的唯一方法是找不到匹配项)。您也可以使用 NOT EXISTS 更清楚地执行此操作,但使用双 LEFT OUTER JOIN 时性能通常会更好。这是一个不存在的版本:

SELECT
    T1.TransID,
    T1.TenantID,
    T1.TransactionType,
    T1.Amount,
    T1.TransactionDate,
    T2.TransactionDate AS PreviousPaymentDate
FROM
    Transactions T1
LEFT OUTER JOIN Transactions T2 ON
    T2.TenantID = T1.TenantID AND
    T2.TransactionType = 2 AND
    T2.TransactionDate < T1.TransactionDate
WHERE
    NOT EXISTS (
        SELECT *
        FROM Transactions T3
        WHERE
            T3.TenantID = T2.TenantID AND
            T3.TransactionType = 2 AND
            T3.TransactionDate < T1.TransactionDate AND
            T3.TransactionDate > T1.TransactionDate
        ) AND
    <your normal selection criteria>

【讨论】:

    猜你喜欢
    • 2011-08-24
    • 2018-10-14
    • 2021-06-04
    • 2019-02-28
    • 2020-06-02
    • 2020-09-25
    • 2012-06-18
    • 1970-01-01
    • 2016-05-18
    相关资源
    最近更新 更多