MySQL选择总和等于的行

时间:2019-02-14 08:27:14

标签: mysql

我有一个像这样的表A:

ID | AMOUNT
1  | 10
2  | 30
3  | 40

我想找到行的总和等于一个值。

例如,如果我将总数设为70,则查询必须返回ID 2和3

2 个答案:

答案 0 :(得分:0)

以下查询将返回两行的列表,其总和等于您传递的值。如果匹配总和的行组合超过一个,它将返回多个列表。在Fiddle上进行检查。您只需要传递所需的总金额,而不是 70

SELECT If((t1.amount+t2.amount)=6,CONCAT(LEAST(t1.id,t2.id),',',GREATEST(t1.id,t2.id)),"") AS sumIds 
FROM testSum t1, testSum t2
WHERE (t1.amount+t2.amount)=6
AND t1.id!=t2.id
GROUP BY sumIds

答案 1 :(得分:0)

您知道每一行的链接行的值应该是多少(70量),因此,给定这一行,您可以为每一行生成最小和最大数量,并基于该块中的minamount和行号生成一个blockid。例如给出的

+------+--------+
| id   | amount |
+------+--------+
|    1 |     10 |
|    2 |     30 |
|    3 |     40 |
|    4 |     70 |
|    5 |     35 |
|    6 |     35 |
|    7 |     35 |
|    8 |     35 |
|    9 |     40 |
|   10 |     60 |
|   11 |     60 |
+------+--------+
11 rows in set (0.00 sec)

select id oldid,amount,
        70 - amount matching_amount,
        case when amount = 70 then 0
            when amount < 70 - amount then amount
            when amount >= 70 - amount then 70 - amount
        end as minamount,
        case when amount = 70 then amount
            when amount < 70 - amount then 70 - amount
            when amount >= 70 - amount then amount
        end as maxamount
from t
) s
cross join (select @bn:=0,@rn:=0,@pid:=0,@pmin:=999999) b
order by minamount,oldid;

你得到

+-------+-----------+-----------+---------+-----------+------+
| oldid | minamount | maxamount | blockid | rownumber | pmin |
+-------+-----------+-----------+---------+-----------+------+
|     4 |         0 |        70 | 1       |         1 |    0 |
|     1 |        10 |        60 | 2       |         1 |   10 |
|    10 |        10 |        60 | 2       |         2 |   10 |
|    11 |        10 |        60 | 2       |         3 |   10 |
|     2 |        30 |        40 | 3       |         1 |   30 |
|     3 |        30 |        40 | 3       |         2 |   30 |
|     9 |        30 |        40 | 3       |         3 |   30 |
|     5 |        35 |        35 | 4       |         1 |   35 |
|     6 |        35 |        35 | 4       |         2 |   35 |
|     7 |        35 |        35 | 4       |         3 |   35 |
|     8 |        35 |        35 | 4       |         4 |   35 |
+-------+-----------+-----------+---------+-----------+------+
11 rows in set (0.00 sec)

如果您再次执行相同的操作,并且在blockid中使偶数行的偶数行变为偶数

select x.oldid,x.minamount,x.maxamount,x.blockid,x.rownumber, y.oldid,
        y.minamount,y.maxamount,y.blockid,y.rownumber
from
(
select oldid,minamount,maxamount,
        if(minamount <> @pmin,@bn:=@bn+1,@bn:=@bn) blockid,
        if(minamount <> @pmin,@rn:=1,@rn:=@rn+1) rownumber,
        @pmin:=minamount pmin
from
(
select id oldid,amount,
        70 - amount matching_amount,
        case when amount = 70 then 0
            when amount < 70 - amount then amount
            when amount >= 70 - amount then 70 - amount
        end as minamount,
        case when amount = 70 then amount
            when amount < 70 - amount then 70 - amount
            when amount >= 70 - amount then amount
        end as maxamount
from t
) s
cross join (select @bn:=0,@rn:=0,@pid:=0,@pmin:=999999) b
order by minamount,oldid
) x
left join
(
select oldid,minamount,maxamount,
        if(minamount <> @pmin1,@bn1:=@bn1+1,@bn1:=@bn1) blockid,
        if(minamount <> @pmin1,@rn1:=1,@rn1:=@rn1+1) rownumber,
        @pmin1:=minamount pmin
from
(
select id oldid,amount,
        70 - amount matching_amount,
        case when amount = 70 then 0
            when amount < 70 - amount then amount
            when amount >= 70 - amount then 70 - amount
        end as minamount,
        case when amount = 70 then amount
            when amount < 70 - amount then 70 - amount
            when amount >= 70 - amount then amount
        end as maxamount
from t
) a
cross join (select @bn1:=0,@rn1:=0,@pid1:=0,@pmin1:=999999) b
order by minamount,oldid
) y
on y.blockid = x.blockid and y.rownumber = x.rownumber + 1
where (x.rownumber % 2 > 0 and y.oldid is not null) or
        (x.rownumber % 2 > 0 and x.minamount = 0)
order by x.oldid;

您得到

+-------+-----------+-----------+---------+-----------+-------+-----------+-----------+---------+-----------+
| oldid | minamount | maxamount | blockid | rownumber | oldid | minamount | maxamount | blockid | rownumber |
+-------+-----------+-----------+---------+-----------+-------+-----------+-----------+---------+-----------+
|     1 |        10 |        60 | 2       |         1 |    10 |        10 |        60 | 2       |         2 |
|     2 |        30 |        40 | 3       |         1 |     3 |        30 |        40 | 3       |         2 |
|     4 |         0 |        70 | 1       |         1 |  NULL |      NULL |      NULL | NULL    |      NULL |
|     5 |        35 |        35 | 4       |         1 |     6 |        35 |        35 | 4       |         2 |
|     7 |        35 |        35 | 4       |         3 |     8 |        35 |        35 | 4       |         4 |
+-------+-----------+-----------+---------+-----------+-------+-----------+-----------+---------+-----------+
5 rows in set (0.10 sec)

在版本8或更高版本中,可以使用row_number函数简化行号模拟