【问题标题】:How to find negative number in a column, which is followed by a positive number如何在列中找到负数,然后是正数
【发布时间】:2014-12-28 01:42:09
【问题描述】:

我有一个历史表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 的行。

【问题讨论】:

  • 请添加标签以显示您正在使用的特定数据库平台
  • 嗨,对不起。我正在使用 Oracle 开发人员
  • 你的例子有点混乱。第 05 和 09 行是 person_ids 05 和 06 的最后一行。
  • 是的,没错。我想尽可能清楚地表明我不希望 Person_ID 05 第 02 行和 Person_ID 06 第 07 行。原因是我需要查看每个 Person_ID 欠债的天数。我希望现在很清楚,如果没有,请询​​问,我会尽快回答:)

标签: sql oracle negative-number


【解决方案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 最后一行将为空。

来源analytic functionsLEAD

【讨论】:

  • 谢谢! :),它不起作用,它显示的是重复的 Person_ID 记录,而不是 Balance_on_account 到实际日期的记录,但我认为 LEAD 可能是答案。我正在尝试所有我想到的东西,但到目前为止没有结果。
  • 您只需要每个人的最后一个余额吗?
  • @Yte 请将您期望的结果添加到您的示例中。
  • 请在您的问题示例中添加您期望的结果(哪些行)。
  • 嗨,我已经这样做了 - 在上面的评论中我正在重播给你>> “是的,那是正确的。我想尽可能清楚地表明我不想Person_ID 05 第 02 行,对于 Person_ID 06 第 07 行。原因是我需要查看每个 Person_ID 欠债的天数。我希望现在很清楚,如果没有,请询​​问,我会尽快回答 :) "
【解决方案2】:

如果您使用的数据库平台支持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

【讨论】:

  • 谢谢,但我恐怕不能在我的 Oracle Developer 中使用它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
相关资源
最近更新 更多