如何获得总计特定值的行的随机组合?

时间:2019-06-30 16:43:43

标签: php mysql sql mariadb-10.1

我的桌子:

+--------------+--------------------+-------------+
|item_id       |        amount      |      sum    |
+--------------+--------------------+-------------+
|2             |2                   |8            |
|3             |1                   |2            |
+--------------+--------------------+-------------+

SQL查询结果应为: 总数为10的项目的随机组合,以及可变数量的不同项目(在本例中为2)。

extends Node2D
slave func set_name(name):

    pass

func set_name_rpc(name):
    rpc("set_name", name)
    pass

结果显示

您得到2乘以2(值4,所以总和为8)。

您将获得一个时间项3(值为2)

此组合总计为10。

即使不是总是相同的组合,如果还有其他可能性也是随机选择的,那是否有可能?

2 个答案:

答案 0 :(得分:1)

您可以使用自联接获取所有此类组合:

select t1.item_id, t2.item_id
from t t1 join
     t t2
     on t1.value + t2.value = 10;

这会将值放在列而不是单独的行上。

答案 1 :(得分:0)

假设您想要一个随机组合,则可以执行以下操作:

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

每次运行此查询时,它都会选择一个随机的[不同]解决方案。

用于创建您提到的表和数据(我曾经测试过)的脚本为:

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);

编辑,2019年7月1日:根据要求,这是一个等效的[更短]解决方案,它使用递归CTE(公用表表达式),自10.2.2起在MariaDB中可用(请参阅{{3} }):

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

如果您需要使用更大的数字,此解决方案的扩展性会更好。