我们如何根据标准重置'OVER(ORDER BY <FIELD> ROWS BETWEEN UNBounded PRECEDING 和当前行)?

Posted

技术标签:

【中文标题】我们如何根据标准重置\'OVER(ORDER BY <FIELD> ROWS BETWEEN UNBounded PRECEDING 和当前行)?【英文标题】:How do we reset 'OVER(ORDER BY <FIELD> ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) Based on Criteria?我们如何根据标准重置'OVER(ORDER BY <FIELD> ROWS BETWEEN UNBounded PRECEDING 和当前行)? 【发布时间】:2019-08-22 07:06:35 【问题描述】:

我正在尝试重置

    SUM(ISNULL(T1.Debit,0) - ISNULL(T1.Credit,0)) OVER(ORDER BY T1.RefDate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 'Balance at Current Time'

每次当前行的第 1 列的单元格与前一个单元格不同时,无需创建使查询执行时间大约需要 10 分钟的 CURSOR。就速度而言,执行此操作的最有效方式似乎是什么。

我将查询转换为使用游标运行,该游标循环通过更改的字段,并且 SUM 在必要时重置。

没有重置的初始查询

DECLARE @fd datetime
DECLARE @td datetime
SET @fd='20001231'
SET @td='20191231'
SELECT 
    T2.CardCode,
    T2.CardName,
    T1.TransId,
    T1.TransType,
    T1.BaseRef,
    CASE 
    WHEN T1.TransType=13 THEN
    (SELECT Z1.CANCELED FROM OINV Z1 WHERE Z1.TransId=T1.TransId)
    WHEN T1.TransType=14 THEN
    (SELECT Z1.CANCELED FROM ORIN Z1 WHERE Z1.TransId=T1.TransId)
    WHEN T1.TransType=18 THEN
    (SELECT Z1.CANCELED FROM OPCH Z1 WHERE Z1.TransId=T1.TransId)
    WHEN T1.TransType=19 THEN
    (SELECT Z1.CANCELED FROM ORPC Z1 WHERE Z1.TransId=T1.TransId)
    WHEN T1.TransType=24 THEN
    (SELECT Z1.CANCELED FROM ORCT Z1 WHERE Z1.TransId=T1.TransId)
    WHEN T1.TransType=46 THEN
    (SELECT Z1.CANCELED FROM OVPM Z1 WHERE Z1.TransId=T1.TransId)
    ELSE 'N' END [Canceled],
    T1.RefDate,
    T1.DueDate,
    T1.TaxDate,
    T1.LineMemo,
    ISNULL(T1.Debit,0) [Debit],
    ISNULL(T1.Credit,0) [Credit],
    ISNULL(
    (SELECT SUM(ISNULL(Z1.Debit,0) - ISNULL(Z1.Credit,0)) 
        FROM OJDT Z0 LEFT OUTER JOIN JDT1 Z1 ON Z1.TransId=Z0.TransID 
        WHERE Z1.ShortName=T2.CardCode AND (Z1.TransType=-2 OR Z0.RefDate<=@td)),0) [Balance],


        SUM(ISNULL(T1.Debit,0) - ISNULL(T1.Credit,0)) OVER(ORDER BY T1.RefDate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 'Balance at Current Time'




FROM OJDT T0
LEFT OUTER JOIN JDT1 T1 ON T1.TransId=T0.TransId
LEFT OUTER JOIN OCRD T2 ON T2.CardCode=T1.ShortName

WHERE ((T0.RefDate>=@fd AND T0.RefDate<=@td)

AND ISNULL(T1.ShortName,'') in (Select CardCode from OCRD where CardType = 'C'))
ORDER BY CardCode, RefDate

游标查询在循环区域内包含上述内容并获取每个 CardCode

使用光标时,查询仍在执行,并且已经超过 10 分钟。我在上面发布的基本查询最多在 1-2 秒内完成运行。

【问题讨论】:

【参考方案1】:

您正在寻找的似乎是“partition by”子句。这将为遇到的每个新卡代码重置总和窗口

SUM(ISNULL(T1.Debit,0) - ISNULL(T1.Credit,0)) OVER( partition by T2.CardCode  ORDER BY T1.RefDate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 'Balance at Current Time'

【讨论】:

以上是关于我们如何根据标准重置'OVER(ORDER BY <FIELD> ROWS BETWEEN UNBounded PRECEDING 和当前行)?的主要内容,如果未能解决你的问题,请参考以下文章

clickhouse实践clickhouse中如何实现ROW_NUMBER() OVER(PARTITION BY ‘xxx‘ ORDER BY ‘xxx‘ DESC/ASC)

clickhouse实践clickhouse中如何实现ROW_NUMBER() OVER(PARTITION BY ‘xxx‘ ORDER BY ‘xxx‘ DESC/ASC)

row_number() over (partition by....order by...)用法 分组排序

如何在具有现有 order by 的表上使用 OVER(ORDER BY())?

DENSE_RANK() OVER (Order by UniqueIdentifer) 问题

如何在 over 函数中使用 partition by 和 order by?