使用SQL使用列的值选择所有可能的行集

时间:2019-04-01 00:35:26

标签: sql

我想知道是否只有SQL才能做到这一点。我要在这里实现的目标如下:

具有以下列的SQL表:

https://webhooks.twilio.com/v1/Accounts/<account_sid>/Flows/<flow_sid>

我要从小于或大于给定值的每一行中选择满足DURATION之和的所有可能的行集。例如,如果值是20,则小于20的结果应包含3组行

  

14 + 5

     

5 + 3

     

14 + 3

3 个答案:

答案 0 :(得分:3)

考虑一个自联接,避免反向重复,条件是两个字段的总和小于零。注意:这只会返回两对组合。

SELECT t1.DURATION, t2.DURATION
FROM myTable t1
LEFT JOIN myTable t2
  ON t1.DURATION < t2.DURATION
WHERE t1.DURATION + t2.DURATION < 20

答案 1 :(得分:2)

这是一个递归CTE解决方案(需要MySQL 8.0+),用于查找总和小于给定值的行总和的所有组合。如果您没有MySQL 8,则可能需要编写一个存储过程来执行相同的循环。

WITH RECURSIVE cte AS (
  SELECT duration,
         duration AS total_duration,
         CAST(duration AS CHAR(100)) AS duration_list 
  FROM test
  WHERE duration < 20
  UNION ALL
  SELECT test.duration,
         test.duration + cte.total_duration, 
         CONCAT(cte.duration_list, ' + ', test.duration)
  FROM test
  JOIN cte ON test.duration > cte.duration AND
              test.duration + cte.total_duration < 20)
SELECT duration_list, total_duration
FROM cte
WHERE duration_list != total_duration
ORDER BY total_duration ASC

我的demo on dbfiddle的示例输出:

duration_list   total_duration
2 + 3           5
2 + 5           7
3 + 5           8
2 + 8           10
2 + 3 + 5       10
3 + 8           11
2 + 11          13
5 + 8           13
2 + 3 + 8       13
3 + 11          14
2 + 5 + 8       15
5 + 11          16
2 + 3 + 11      16
3 + 5 + 8       16
2 + 14          16
3 + 14          17
2 + 5 + 11      18
2 + 3 + 5 + 8   18
2 + 3 + 14      19
3 + 5 + 11      19
8 + 11          19
5 + 14          19

答案 2 :(得分:1)

您可以使用Common Table Expressions解决问题。您应该拥有MySQL 8.0。

请参阅下文。

WITH cte (duration) AS (
    SELECT duration 
      FROM your_table
     WHERE duration  < 20
)
SELECT a.duration + b.duration AS 'sum_of_val'
  FROM cte a JOIN cte b 
 WHERE a.duration + b.duration < 20

如果您拥有不支持CTE的其他版本,则可以使用子查询。

请参阅下文。

SELECT a.duration + b.duration AS 'sum_of_val'
  FROM (select duration from your_table where duration < 20 ) a
       JOIN (select duration from your_table where duration <20 ) b
 WHERE a.duration + b.duration < 20