Home > Software engineering >  All possible combinations of data in a single table in alphabetical order
All possible combinations of data in a single table in alphabetical order

Time:02-11

I'm trying to write a simple SQL query to show all possible combinations of data in a single table. Here's the table:

id fruit
1 apple
2 orange
3 pear
4 plum

I've only got as fair as pairing all the data using CROSS JOIN: "apple,orange", "apple,pear" etc.

SELECT t1.fruit, t2.fruit
FROM fruits t1
CROSS JOIN fruits t2
WHERE t1.fruit < t2.fruit

Instead I'm looking for all unique combinations in alphabetical order, e.g.

  • apple
  • apple,orange
  • apple,orange,pear
  • apple,orange,pear,plum
  • apple,pear
  • apple,plum
  • apple,orange,plum
  • apple,pear,plum
  • orange
  • orange,pear
  • orange,pear,plum
  • orange,plum
  • pear
  • pear,plum
  • plum

i.e. as long as a combination exists once, it doesn't need to appear again in a different order, e.g. with apple,orange, there is no need for orange,apple

CodePudding user response:

Below query should work:

WITH RECURSIVE cte AS (
    SELECT A.id,
        CONCAT(A.fruit,',',GROUP_CONCAT(B.fruit ORDER BY B.id)) AS combinations,
        COUNT(*) AS count_of_delims 
    FROM fruits A 
    INNER JOIN fruits B 
    ON A.id<B.id 
    GROUP BY A.id,A.fruit
  
    UNION ALL
  
    SELECT id,
        SUBSTRING_INDEX(combinations,',',count_of_delims),
        count_of_delims-1 
    FROM cte 
    WHERE count_of_delims>0
)
SELECT combinations FROM cte ORDER BY id;

Here is a working example in DB Fiddle.

CodePudding user response:

Here is a very ugly solution that works (try here):

SELECT
    CONCAT(T.t1,
        CONCAT(IF(T.t2 IS NULL, '',
            CONCAT(', ', T.t2)) ,
            CONCAT(IF(T.t3 IS NULL, '',
                CONCAT(', ', T.t3)) , IF(T.t4 IS NULL, '',
                CONCAT(', ', T.t4))
            )
        )
    )
              
'result' FROM

(

    SELECT T1.fruit 't1', TX.* FROM fruits T1
    LEFT JOIN (

        SELECT T2.fruit 't2', TY.* FROM fruits T2
        LEFT JOIN (

                  SELECT T3.fruit 't3', t4 't4' FROM fruits T3
                  LEFT JOIN (

                    SELECT T4.fruit 't4' FROM fruits T4 WHERE id = 4

                  ) TZ
                    ON T3.fruit < t4
                  WHERE T3.fruit > 'orange'
                  UNION ALL
                  SELECT fruit, null FROM fruits WHERE id = 3
          
        ) TY
          ON T2.fruit < t3
        WHERE T2.fruit > 'apple'
        UNION ALL
        SELECT fruit, null, null FROM fruits WHERE id IN (3, 2)

    ) TX
      ON T1.fruit < t2
    UNION ALL
    SELECT fruit, null, null, null FROM fruits WHERE id IN (3, 2, 1)

) T

ORDER BY t1, t2, t3, t4

Result:

 --------------------------- 
|          result           |
 --------------------------- 
| apple                     |
| apple, orange             |
| apple, orange, pear       |
| apple, orange, pear, plum |
| apple, orange, plum       |
| apple, pear               |
| apple, pear, plum         |
| apple, plum               |
| orange                    |
| orange, pear              |
| orange, pear, plum        |
| orange, plum              |
| pear                      |
| pear, plum                |
| plum                      |
 --------------------------- 
  • Related