Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 310
  • Last Modified:

Creating Combinations

Hi
How can SQL be used to create all possible combinations for a data set containing (A,B,C)? The result I require is: (A),(B),(C),(A,B),(A,C),(B,C)(A,B,C) – note order doesn’t matter so (B,A),(C,A),(C,B),(B,C,A) etc should not be returned.
Thanks
0
antonms
Asked:
antonms
  • 4
  • 3
  • 3
  • +2
4 Solutions
 
dsackerContract ERP Admin/ConsultantCommented:
Are these three columns from three different tables, or are they values from one column that you wish to be spread across?
0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
with recursive sql, 1 single shot  (sql 2005+)
declare @set table ( v varchar(100 ) )
insert into @set values ('A')
insert into @set values ('B')
insert into @set values ('C')

; with x ( v , l ) as (
  select v , 0 
    from @set 
  UNION ALL
  select cast(x.v + s.v as varchar(100)) , x.l+1
    from x
    join @set s on x.v not like '%' + s.v + '%' and s.v > right(x.v,1)
)
select * from x

Open in new window

0
 
HainKurtSr. System AnalystCommented:
hmmss...  maybe this help:
with 
a as (select 'A' p union select 'B' union select 'C'), 
b as (select 'A' p union select 'B' union select 'C' union select null), 
c as (select 'A' p union select 'B' union select 'C' union select null) 
select a.p,b.p, c.p 
from a left join b on (b.p>a.p or b.p is null) left join c on (c.p>b.p or c.p is null)

p	p	p
A	NULL	NULL
A	B	NULL
A	B	C
A	C	NULL
B	NULL	NULL
B	C	NULL
C	NULL	NULL

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
HainKurtSr. System AnalystCommented:
or with one table
with 
a as (select 'A' p union select 'B' union select 'C' union select null) 
select a.p,b.p, c.p 
from a a left join a b on (b.p>a.p or b.p is null) left join a c on (c.p>b.p or c.p is null)

p	p	p
NULL	NULL	NULL
A	NULL	NULL
A	B	NULL
A	B	C
A	C	NULL
B	NULL	NULL
B	C	NULL
C	NULL	NULL

Open in new window

0
 
antonmsAuthor Commented:
Thanks guys for the super fast replies!
I'll need  to mull over you suggestions and get right back.
0
 
lluddenCommented:
WITH cte1 AS
(SELECT 'A' AS Val UNION SELECT 'B' UNION SELECT 'C' UNION SELECT NULL)

SELECT * FROM cte1 A CROSS JOIN cte1 B CROSS JOIN cte1 C
0
 
HainKurtSr. System AnalystCommented:
"CROSS JOIN" solution posted by lludden gives 4x4x4=64 result...
0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
just a note that my suggestion will dynamically return as many rows as you have in the base set, so if you have 1 or 100 items, it will work ....
0
 
antonmsAuthor Commented:
I should have mentioned that the solution has to work on SQL Server 2000 SP4 onwards. So I need to also think about how to insert the results in to a table - possibly via pivot - I'll update on Monday - many thanks to all.
0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
if it needs to be sql 2000, you indeed need to first create a table that has as many columns as you have values to start with.
and then, for each number of "columns" to be returned, build the sql to "cross join" as needed to get the results...
0
 
lluddenCommented:
DECLARE @T TABLE(
      val CHAR(1)
)
INSERT
INTO @T
SELECT 'A' UNION
SELECT 'B' UNION
SELECT 'C' UNION
SELECT ''

SELECT DISTINCT *
FROM (
SELECT t1.val AS Val1,
         CASE WHEN t2.val <> '' THEN T2.val ELSE t2.val END AS val2,
         CASE WHEN t2.val = '' THEN '' ELSE t3.val END AS val3
FROM @T t1
      CROSS JOIN @T t2
      CROSS JOIN @T t3
WHERE t1.val <> t2.val
      AND t1.val <> t3.val
      AND t2.val <> t3.val
      AND t1.val <> ''
      AND t2.val <> 'A'
      AND t3.val IN ('','C')
) T0

0
 
antonmsAuthor Commented:
Thanks chaps - how could these approaches be developed into a procedure were the procedure was provided with a list of the elements. each element in the list would be unique but the number of elements was unknown - I know this is a big ask but I'm struggling to find a solution.
0
 
lluddenCommented:
First of all, keep in mind that TSQL is primarily a language for working with sets of data on a well defined table.  This is a more analytical type of problem that would be better suited to another language.  There are some good examples such as http://www.codeproject.com/KB/recipes/Combinatorics.aspx or http://www2.sas.com/proceedings/sugi23/Posters/p177.pdf

It can be done in SQL.  You will have to either accept that each line returned is a single field treated as a delimited list, or define a max list size and accept null values for smaller than max list size.
0
 
antonmsAuthor Commented:
Perms, Combination and Variation operators would be a great addition to T SQL.
0

Featured Post

Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

  • 4
  • 3
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now