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