sql - 查询所需数据的更好方法

sql - better way of querying required data

我有这张 table 快照

A | B   | C  | D
o1| 100 | 20 | i1
o2| 100 | 30 | i1

对于给定的数字,我需要行直到 sum(B-C) >= given_number

例如:

我正在使用 informix 数据库。也请建议 mysql 具体的解决方案,我会尝试 informix 等价物。

使用 Informix 12.10.FC8DE 也许下面就是你想要的。

CREATE TABLE test_data
(
    a CHAR(2)
    , b INTEGER
    , c INTEGER
    , d CHAR(2)
);

INSERT INTO test_data VALUES('o1', 100,  20, 'i1');
INSERT INTO test_data VALUES('o2', 100,  30, 'i1');
INSERT INTO test_data VALUES('o3', 100,  15, 'i1');
INSERT INTO test_data VALUES('o4', 100,  45, 'i1');
INSERT INTO test_data VALUES('o5', 100,  20, 'i2');
INSERT INTO test_data VALUES('o6', 100, 100, 'i1');
INSERT INTO test_data VALUES('o7', 100,  30, 'i2');
INSERT INTO test_data VALUES('o8', 100,   5, 'i2');
INSERT INTO test_data VALUES('o9', 100,  60, 'i1');

SELECT * FROM test_data;
a            b           c d    
o1         100          20 i1
o2         100          30 i1
o3         100          15 i1
o4         100          45 i1
o5         100          20 i2
o6         100         100 i1
o7         100          30 i2
o8         100           5 i2
o9         100          60 i1
 9 row(s) retrieved.

有了这个示例数据,我们可以使用(为了更好地可视化,我留下了累积总和)请求 (i1, 80):

SELECT
    *
FROM
(
SELECT
    *
    , SUM (t.b - t.c) 
        OVER 
        (
            ORDER BY t.a
            ROWS BETWEEN UNBOUNDED PRECEDING
            AND CURRENT ROW
        ) AS r_sum 
    , SUM (t.b - t.c) 
        OVER 
        (
            ORDER BY t.a
            ROWS BETWEEN UNBOUNDED PRECEDING
            AND 1 PRECEDING
        ) AS previous_r_sum

FROM
    test_data AS t
WHERE
    t.d = 'i1'
) AS vt1
WHERE
    previous_r_sum < 80 
    OR previous_r_sum IS NULL;

a            b           c d             r_sum   previous_r_sum    
o1         100          20 i1               80
 1 row(s) retrieved.

有了这个示例数据,我们可以使用(为了更好地可视化,我留下了累积总和)请求 (i1, 100):

SELECT
    *
FROM
(
SELECT
    *
    , SUM (t.b - t.c) 
        OVER 
        (
            ORDER BY t.a
            ROWS BETWEEN UNBOUNDED PRECEDING
            AND CURRENT ROW
        ) AS r_sum 
    , SUM (t.b - t.c) 
        OVER 
        (
            ORDER BY t.a
            ROWS BETWEEN UNBOUNDED PRECEDING
            AND 1 PRECEDING
        ) AS previous_r_sum

FROM
    test_data AS t
WHERE
    t.d = 'i1'
) AS vt1
WHERE
    previous_r_sum < 100
    OR previous_r_sum IS NULL;

a            b           c d             r_sum   previous_r_sum
o1         100          20 i1               80
o2         100          30 i1              150               80
 2 row(s) retrieved.

我没有进行任何性能或极端情况测试。