Php 如何获得求和为特定值的行的随机组合?
我的表格如下:Php 如何获得求和为特定值的行的随机组合?,php,mysql,sql,mariadb-10.1,Php,Mysql,Sql,Mariadb 10.1,我的表格如下: +--------+--------------------+ |item_id| value | +--------+--------------------+ | 1 | 1 | | 2 | 4 | | 3 | 2 | | 4 | 6 | +--------+--------
+--------+--------------------+
|item_id| value |
+--------+--------------------+
| 1 | 1 |
| 2 | 4 |
| 3 | 2 |
| 4 | 6 |
+--------+--------------------+
SQL查询结果应该是什么:
总和为10的项目的随机组合,在这种情况下,不同项目的数量可变2
+--------------+--------------------+-------------+
|item_id | amount | sum |
+--------------+--------------------+-------------+
|2 |2 |8 |
|3 |1 |2 |
+--------------+--------------------+-------------+
结果显示
第2项的值为4,因此它加起来等于8
得到一个时间项3,其值为2
这一组合总计为10。
如果不应该是相同的组合,则如果存在其他可能性,则始终随机选择该组合,这是可能的吗?您可以使用自联接获得所有此类组合:
select t1.item_id, t2.item_id
from t t1 join
t t2
on t1.value + t2.value = 10;
这会将值放在列上,而不是单独的行中。如果需要单个随机组合,可以执行以下操作:
select
*
from (
select
a.item_id as item1,
x.n as amount1,
a.value * x.n as sum1,
b.item_id as item2,
y.n as amount2,
b.value * y.n as sum2,
rand() as r
from my_table a
join my_table b on b.item_id <> a.item_id
cross join (
select 1 as n union select 2 union select 3 union select 4
union select 5 union select 6 union select 7 union select 8
union select 9 union select 10) x
cross join (
select 1 as n union select 2 union select 3 union select 4
union select 5 union select 6 union select 7 union select 8
union select 9 union select 10) y
where a.value * x.n + b.value * y.n = 10
) z
order by r -- sorted randomly
limit 1 -- to get only one combination; remove to get them all
2019年7月1日编辑:根据要求,这里有一个使用递归CTE公共表表达式的等效[shorter]解决方案,从10.2.2开始在MariaDB中提供,请参见:
如果您需要使用更高的数字,此解决方案的扩展性更好。您能解释一下逻辑吗?你是如何得到预期的结果的?我添加了更多的信息,如果它有帮助的话,明白了。你有什么数据库引擎,哪个版本?否则我会考虑泛型SQL添加MySQL标签MySQL版本吗?5.x或8.x。这些是完全不同的动物。不确定t2是什么,但也许你理解错了。我更新了question@Darkennt2是对称为t的表的第二个引用。正如答案所说,它是一个自联接:t被联接到它自身的另一个副本上。但它不包括有多个相同项的可能性,正如问题所说的,这就是为什么我说随机组合,因为你不能输出所有项。@Darken。您可以添加限制1以获得一个组合。但是,结果是任意的,而不是随机的。这完全符合预期!假设我想要3个结果为10的项目,我是否需要添加另一个交叉连接?如果总和需要为10以外的值,您是否需要更多的联合选择?@Darken是的,除非您升级到MariaDB 10.2,在那里您可以使用[短]递归CTE生成数字。您能给我看一下10.2版本吗?抱歉,如果要求太多,我也没有sql那么先进。@Darken,就是这样。
create table my_table (
item_id int,
value int
);
insert into my_table (item_id, value) values (1, 1);
insert into my_table (item_id, value) values (2, 4);
insert into my_table (item_id, value) values (3, 2);
insert into my_table (item_id, value) values (4, 6);
with recursive
val as (select 1 as n union all select n + 1 from val where n < 10)
select
*
from (
select
a.item_id as item1,
x.n as amount1,
a.value * x.n as sum1,
b.item_id as item2,
y.n as amount2,
b.value * y.n as sum2,
rand() as r
from my_table a
join my_table b on b.item_id <> a.item_id
cross join val x
cross join val y
where a.value * x.n + b.value * y.n = 10
) z
order by r -- sorted randomly
limit 1 -- to get only one combination; remove to get all 22 answers