如何在列中找到负数,后跟一个正数

时间:2014-10-31 16:53:24

标签: sql oracle negative-number

我有一个包含以下内容的历史表XY

 ID   Person_ID   Balance_on_account   ts
---- ----------- -------------------- ----------
 01   05          +10                  10.10.14
 02   05          -10                  20.10.14
 03   05          -50                  30.10.14
 04   05          +50                  30.10.14
 05   05          -10                  30.10.14
 06   06           11                  11.10.14
 07   06          -40                  15.10.14
 08   06           +5                  16.10.14
 09   06          -10                  30.10.14

我需要创建一个SQL查询,它将为我提供那些Person_ID和时间戳

  • a)Balance_on_account是否定的 - 这很容易,
  • b)同时是负数Balance_on_account后跟正数的记录。

Person_ID = 05类似,我的行为ID = 05,而Person_ID = 06的行为ID = 09

2 个答案:

答案 0 :(得分:1)

我从未使用它,但您可以尝试分析LEAD功能

SELECT * 
FROM (
    SELECT ID, Person_ID, Balance_on_account, ts
           LEAD (Balance_on_account, 1) 
           OVER (PARTITION BY Person_ID ORDER BY ID) next_balance
    FROM XY)
WHERE Balance_on_account < 0 and next_balance >= 0
ORDER BY ID

LEAD允许您在查询中访问以下行而无需自行加入。 PARTITION BY按Person_ID对行进行分组,因此它不会混合不同的人的余额,ORDER BY定义每个组中的顺序。 无法在内部查询中进行过滤,因为它会过滤掉具有正余额的行。

对于最后一行,next_balance将为null。

来源analytic functionsLEAD

答案 1 :(得分:0)

如果您使用的数据库平台支持Common Table ExpressionsWindow Functions,则以下查询应该会为您提供预期的结果。 SQL Server 2008及更高版本。

SqlFiddle

WITH TsOrder AS
(
    SELECT
        Id
        , Person_Id
        , Balance_on_account
        , ts
        , ROW_NUMBER() OVER(PARTITION BY Person_Id
                            ORDER BY ts, Id) AS ts_Order

    FROM
        [TableName]
)

SELECT
    *

FROM
    TsOrder
    LEFT JOIN TsOrder AS NextTs
        ON  TsOrder.Person_id = NextTs.Person_Id
            AND TsOrder.ts_order = NextTs.ts_order - 1

WHERE
    TsOrder.Balance_on_account < 0
    AND NextTs.Balance_on_account > 0