Если вы хотите учитывать только последовательные дни, то:
SELECT AccountId
FROM (
SELECT Accountid, DateTime, Balance,
SUM( has_changed_sign )
OVER ( PARTITION BY AccountId ORDER BY DateTime )
AS grp
FROM (
SELECT Accountid, DateTime, Balance,
CASE
WHEN SIGN( balance )
= LAG( SIGN( Balance ) )
OVER ( PARTITION BY AccountId ORDER BY DateTime )
THEN 0
ELSE 1
END AS has_changed_sign
FROM table_name t
)
WHERE Balance < 0
)
GROUP BY AccountID, grp
HAVING COUNT(*) > 2
Итак, для тестовых данных:
CREATE TABLE table_name ( Accountid, DateTime, Balance ) AS
SELECT 1000, DATE '2020-01-01', -1.00 FROM DUAL UNION ALL -- 3 consecutive -ve days
SELECT 1000, DATE '2020-01-02', -1.00 FROM DUAL UNION ALL
SELECT 1000, DATE '2020-01-03', -1.00 FROM DUAL UNION ALL
SELECT 1000, DATE '2020-01-04', +1.00 FROM DUAL UNION ALL
SELECT 1001, DATE '2020-01-01', -20.00 FROM DUAL UNION ALL -- Only 2 negative
SELECT 1001, DATE '2020-01-02', -20.00 FROM DUAL UNION ALL
SELECT 1001, DATE '2020-01-03', +20.00 FROM DUAL UNION ALL
SELECT 1001, DATE '2020-01-04', +20.00 FROM DUAL UNION ALL
SELECT 1002, DATE '2020-01-01', -1.00 FROM DUAL UNION ALL -- 3 negative days but
SELECT 1002, DATE '2020-01-02', -1.00 FROM DUAL UNION ALL -- only 2 consecutive
SELECT 1002, DATE '2020-01-03', +1.00 FROM DUAL UNION ALL
SELECT 1002, DATE '2020-01-04', -1.00 FROM DUAL UNION ALL
SELECT 1003, DATE '2020-01-01', +15.00 FROM DUAL UNION ALL -- All positive
SELECT 1003, DATE '2020-01-02', +16.00 FROM DUAL UNION ALL
SELECT 1003, DATE '2020-01-03', +17.00 FROM DUAL UNION ALL
SELECT 1003, DATE '2020-01-04', +18.00 FROM DUAL;
Это выводит:
| ACCOUNTID |
| --------: |
| 1000 |
Если вам нужно больше, чем 2 дня, тогда вы можете просто использовать LAG
:
SELECT DISTINCT
AccountID
FROM (
SELECT AccountID,
balance,
LAG( balance, 1 ) OVER ( PARTITION BY AccountID ORDER BY DateTime )
AS balance_1_day_ago,
LAG( balance, 2 ) OVER ( PARTITION BY AccountID ORDER BY DateTime )
AS balance_2_days_ago
FROM table_name
)
WHERE balance < 0
AND balance_1_day_ago < 0
AND balance_2_days_ago < 0;
Но это не будет хорошо масштабироваться, если вы хотите проверить больший период поскольку запрос быстро станет очень большим.
db <> fiddle здесь