Solved

Creating Combinations

Posted on 2011-09-16
14
296 Views
Last Modified: 2012-05-12
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
Comment
Question by:antonms
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 3
  • +2
14 Comments
 
LVL 20

Expert Comment

by:dsacker
ID: 36549558
Are these three columns from three different tables, or are they values from one column that you wish to be spread across?
0
 
LVL 143

Assisted Solution

by:Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3] earned 125 total points
ID: 36549604
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
 
LVL 52

Expert Comment

by:Huseyin KAHRAMAN
ID: 36549646
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
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 52

Accepted Solution

by:
Huseyin KAHRAMAN earned 125 total points
ID: 36549656
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
 

Author Comment

by:antonms
ID: 36549748
Thanks guys for the super fast replies!
I'll need  to mull over you suggestions and get right back.
0
 
LVL 18

Assisted Solution

by:lludden
lludden earned 250 total points
ID: 36551522
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
 
LVL 52

Expert Comment

by:Huseyin KAHRAMAN
ID: 36551617
"CROSS JOIN" solution posted by lludden gives 4x4x4=64 result...
0
 
LVL 143

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 36553358
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
 

Author Comment

by:antonms
ID: 36554078
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
 
LVL 143

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 36554364
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
 
LVL 18

Assisted Solution

by:lludden
lludden earned 250 total points
ID: 36563426
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
 

Author Comment

by:antonms
ID: 36573487
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
 
LVL 18

Expert Comment

by:lludden
ID: 36573735
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
 

Author Closing Comment

by:antonms
ID: 36576709
Perms, Combination and Variation operators would be a great addition to T SQL.
0

Featured Post

Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
The Delta outage: 650 cancelled flights, more than 1200 delayed flights, thousands of frustrated customers, tens of millions of dollars in damages – plus untold reputational damage to one of the world’s most trusted airlines. All due to a catastroph…
This video shows, step by step, how to configure Oracle Heterogeneous Services via the Generic Gateway Agent in order to make a connection from an Oracle session and access a remote SQL Server database table.
Using examples as well as descriptions, and references to Books Online, show the documentation available for datatypes, explain the available data types and show how data can be passed into and out of variables.

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question