基于条件的行组合选择 - MySQL
Row combination choices based on condition - MySQL
我有一个有效的 SQL 查询,returns 结果如下:
我想要做的是让 MySQL 计算权重列的 sum
并呈现上述 table 中的行组合,其中sum(Weight) <= 300
。使用上述 table 的预期结果示例为:
我对此的问题是:MySQL 这可能吗?我是否需要执行多个 SQL 查询,以及如何才能生成上述结果?是否有可能实现第一个 table 和一个查询的组合?
免责声明:我不确定您设想如何从一个查询返回 3 个结果集,以及为什么只有三个 - (1,4) 和 (2,3) 也会是有效的组合。因此,我假设这只是一个一般示例,并且您希望 complete 结果为 some 形式 。
假设您有这个 table(我添加了一行以使其更通用,您的示例只会产生 2 元素组合):
MariaDB [test]> SELECT * FROM t1;
+------+--------+
| id | weight |
+------+--------+
| 1 | 100 |
| 2 | 120 |
| 3 | 200 |
| 4 | 96 |
| 5 | 50 |
+------+--------+
5 rows in set (0.00 sec)
用MariaDB 10.2, you can use a recursive CTE来实现你的目标,例如
WITH RECURSIVE comb(id,ids,weights,sumweight) AS (
SELECT
id,
CAST(t1.id AS CHAR) AS ids,
CAST(weight AS CHAR) AS weights,
weight AS sumweight
FROM t1
WHERE weight <= 300
UNION
SELECT
t1.id AS id,
CONCAT(comb.ids,',',t1.id) AS ids,
CONCAT(comb.weights,',',weight) AS weights,
t1.weight + comb.sumweight AS sumweight
FROM t1 JOIN comb ON (comb.id < t1.id)
HAVING sumweight <= 300
) SELECT ids, weights, sumweight FROM comb;
你会得到这个:
+-------+------------+-----------+
| ids | weights | sumweight |
+-------+------------+-----------+
| 1 | 100 | 100 |
| 2 | 120 | 120 |
| 3 | 200 | 200 |
| 4 | 96 | 96 |
| 5 | 50 | 50 |
| 1,2 | 100,120 | 220 |
| 1,3 | 100,200 | 300 |
| 1,4 | 100,96 | 196 |
| 1,5 | 100,50 | 150 |
| 2,4 | 120,96 | 216 |
| 2,5 | 120,50 | 170 |
| 3,4 | 200,96 | 296 |
| 3,5 | 200,50 | 250 |
| 4,5 | 96,50 | 146 |
| 1,2,5 | 100,120,50 | 270 |
| 1,4,5 | 100,96,50 | 246 |
| 2,4,5 | 120,96,50 | 266 |
+-------+------------+-----------+
17 rows in set (0.00 sec)
上面的查询并不完美,只是给出可能的解决方案的想法。结果似乎是正确的,您可以根据需要改进和完善表示。
你的第二个问题"Is it possible to achieve the first table and the combinations from one query?",你没有说你是怎么得到第一个table的,所以很难给出一个准确的例子,但无论如何它肯定应该是可能的。最明显的方法是采用您用来获取该结果集的任何查询,将其包装到一个视图中,然后使用该视图代替上面示例中的 t1
table。
我有一个有效的 SQL 查询,returns 结果如下:
我想要做的是让 MySQL 计算权重列的 sum
并呈现上述 table 中的行组合,其中sum(Weight) <= 300
。使用上述 table 的预期结果示例为:
我对此的问题是:MySQL 这可能吗?我是否需要执行多个 SQL 查询,以及如何才能生成上述结果?是否有可能实现第一个 table 和一个查询的组合?
免责声明:我不确定您设想如何从一个查询返回 3 个结果集,以及为什么只有三个 - (1,4) 和 (2,3) 也会是有效的组合。因此,我假设这只是一个一般示例,并且您希望 complete 结果为 some 形式 。
假设您有这个 table(我添加了一行以使其更通用,您的示例只会产生 2 元素组合):
MariaDB [test]> SELECT * FROM t1;
+------+--------+
| id | weight |
+------+--------+
| 1 | 100 |
| 2 | 120 |
| 3 | 200 |
| 4 | 96 |
| 5 | 50 |
+------+--------+
5 rows in set (0.00 sec)
用MariaDB 10.2, you can use a recursive CTE来实现你的目标,例如
WITH RECURSIVE comb(id,ids,weights,sumweight) AS (
SELECT
id,
CAST(t1.id AS CHAR) AS ids,
CAST(weight AS CHAR) AS weights,
weight AS sumweight
FROM t1
WHERE weight <= 300
UNION
SELECT
t1.id AS id,
CONCAT(comb.ids,',',t1.id) AS ids,
CONCAT(comb.weights,',',weight) AS weights,
t1.weight + comb.sumweight AS sumweight
FROM t1 JOIN comb ON (comb.id < t1.id)
HAVING sumweight <= 300
) SELECT ids, weights, sumweight FROM comb;
你会得到这个:
+-------+------------+-----------+
| ids | weights | sumweight |
+-------+------------+-----------+
| 1 | 100 | 100 |
| 2 | 120 | 120 |
| 3 | 200 | 200 |
| 4 | 96 | 96 |
| 5 | 50 | 50 |
| 1,2 | 100,120 | 220 |
| 1,3 | 100,200 | 300 |
| 1,4 | 100,96 | 196 |
| 1,5 | 100,50 | 150 |
| 2,4 | 120,96 | 216 |
| 2,5 | 120,50 | 170 |
| 3,4 | 200,96 | 296 |
| 3,5 | 200,50 | 250 |
| 4,5 | 96,50 | 146 |
| 1,2,5 | 100,120,50 | 270 |
| 1,4,5 | 100,96,50 | 246 |
| 2,4,5 | 120,96,50 | 266 |
+-------+------------+-----------+
17 rows in set (0.00 sec)
上面的查询并不完美,只是给出可能的解决方案的想法。结果似乎是正确的,您可以根据需要改进和完善表示。
你的第二个问题"Is it possible to achieve the first table and the combinations from one query?",你没有说你是怎么得到第一个table的,所以很难给出一个准确的例子,但无论如何它肯定应该是可能的。最明显的方法是采用您用来获取该结果集的任何查询,将其包装到一个视图中,然后使用该视图代替上面示例中的 t1
table。