首页 > 解决方案 > SQL查询根据条件减去特定行

问题描述

(我已经重写了我的问题,因为它更复杂)我正在绞尽脑汁思考如何做到这一点。考虑这个例子:

+---------+---------+----------+-----------+--------+-------------+
| IDE_REF | ID_REF2 | CURRENCY | INDICATOR | AMOUNT | TYPE_AMOUNT |
+---------+---------+----------+-----------+--------+-------------+
| 157     |     129 | USD      |         2 |     30 |           1 |
| 157     |     129 | USD      |         2 |     30 |           3 |
| 157     |     129 | USD      |         2 |     30 |           8 |
| 166     |     129 | USD      |         2 |     50 |           1 |
| 166     |     129 | USD      |         2 |     50 |           3 |
| 166     |     129 | USD      |         2 |     50 |           8 |
| 167     |     129 | USD      |         2 |     80 |           1 |
| 167     |     129 | USD      |         2 |     80 |           3 |
| 167     |     129 | USD      |         2 |     80 |           8 |
| NULL    |     129 | NULL     |         2 |     20 |           1 |
| NULL    |     129 | NULL     |         2 |     20 |           3 |
| NULL    |     129 | NULL     |         2 |     20 |           8 |
| 158     |    1234 | USD      |         2 |     10 |           1 |
| 158     |    1234 | USD      |         2 |     10 |           3 |
| 158     |    1234 | USD      |         2 |     10 |           8 |
| NULL    |    1234 | NULL     |         1 |    125 |           1 |
| NULL    |    1234 | NULL     |         1 |    125 |           3 |
| NULL    |    1234 | NULL     |         1 |    125 |           8 |
+---------+---------+----------+-----------+--------+-------------+

说明:如果 IDE_REF 为 NULL,它应该找到第一个匹配的 ID_REF2,其中 IDE_REF 不是 NULL,并根据 INDICATOR 加/减 AMOUNT。所以有可能有多个结果很好。

这很好(20 的数量已添加到 80 = 100,IDE_REF:167,ID_REF2:129):

+---------+---------+----------+-----------+--------+-------------+
| IDE_REF | ID_REF2 | CURRENCY | INDICATOR | AMOUNT | TYPE_AMOUNT |
+---------+---------+----------+-----------+--------+-------------+
|     157 |     129 | USD      |         2 |     30 |           1 |
|     157 |     129 | USD      |         2 |     30 |           3 |
|     157 |     129 | USD      |         2 |     30 |           8 |
|     166 |     129 | USD      |         2 |     50 |           1 |
|     166 |     129 | USD      |         2 |     50 |           3 |
|     166 |     129 | USD      |         2 |     50 |           8 |
|     167 |     129 | USD      |         2 |    100 |           1 |
|     167 |     129 | USD      |         2 |    100 |           3 |
|     167 |     129 | USD      |         2 |    100 |           8 |
|     158 |    1234 | USD      |         1 |    115 |           1 |
|     158 |    1234 | USD      |         1 |    115 |           3 |
|     158 |    1234 | USD      |         1 |    115 |           8 |
+---------+---------+----------+-----------+--------+-------------+

这也很好(20 的数量已添加到 50 = 70,IDE_REF:166,ID_REF2:129):

+---------+---------+----------+-----------+--------+-------------+
| IDE_REF | ID_REF2 | CURRENCY | INDICATOR | AMOUNT | TYPE_AMOUNT |
+---------+---------+----------+-----------+--------+-------------+
|     157 |     129 | USD      |         2 |     30 |           1 |
|     157 |     129 | USD      |         2 |     30 |           3 |
|     157 |     129 | USD      |         2 |     30 |           8 |
|     166 |     129 | USD      |         2 |     70 |           1 |
|     166 |     129 | USD      |         2 |     70 |           3 |
|     166 |     129 | USD      |         2 |     70 |           8 |
|     167 |     129 | USD      |         2 |     80 |           1 |
|     167 |     129 | USD      |         2 |     80 |           3 |
|     167 |     129 | USD      |         2 |     80 |           8 |
|     158 |    1234 | USD      |         1 |    115 |           1 |
|     158 |    1234 | USD      |         1 |    115 |           3 |
|     158 |    1234 | USD      |         1 |    115 |           8 |
+---------+---------+----------+-----------+--------+-------------+

标签: sqlsql-server

解决方案


这回答了问题的原始版本。

您可以使用 ajoin来排列行,然后使用一些条件逻辑:

select t2.ide_ref, t2.id_ref2, t2.currency, 
       coalesce(t1.indicator, t2.indicator),
       (case when t1.indicator = 1 then t1.amount - t2.amount
             else t2.amount
        end) as amount,
       t1.type_amount
from t t2 left join
     t t1
     on t1.ide_ref = t2.ide_ref and
        t1.type_amount = t1.type_amount and
        t1.indicator = 1
where t2.indicator = 2;

推荐阅读