| Author |
Topic  |
|
|
KilpAr
Yak Posting Veteran
80 Posts |
Posted - 07/25/2012 : 06:24:12
|
I want a Cartesian product of X amount of fields (let's say, about 12 or so fields) and then breakdown them into counts. The fields can be at one table
So for example, I have this kind of simple table, named, say, testtable Field1 Field2 Value1 Value2 Value1 Value3 Value4 Value2 Value1 Value3
The Cartesian product is (this table is not necessarily needed and at least the Combination can be formatted in any way, doesn't matter at all) ID Combination 1 Value1Value2 2 Value1Value3 3 Value4Value2 4 Value4Value3
And the result would be Combination Count 1 1 2 2 3 1 4 0
It's important (pretty much the whole point) to have those zero rows there too.
I don't have the final data yet for this, but I think this should be pretty easy to understand that what is wanted. The result might be harder to count though.
If that's impossible (which I think it's not), I could have the full Cartesian product table counted in forehand. |
|
|
SwePeso
Patron Saint of Lost Yaks
Sweden
29138 Posts |
Posted - 07/25/2012 : 07:12:36
|
-- Prepare sample data
DECLARE @Sample TABLE
(
col1 VARCHAR(20) NOT NULL,
col2 VARCHAR(20) NOT NULL
);
INSERT @Sample
(
col1,
col2
)
VALUES ('Value1', 'Value2'),
('Value1', 'Value3'),
('Value4', 'Value2'),
('Value3', 'Value1');
-- Solution by SwePeso
CREATE TABLE #Cols
(
col1 VARCHAR(20) NOT NULL,
col2 VARCHAR(20) NOT NULL,
cnt INT NOT NULL
);
INSERT #Cols
(
col1,
col2,
cnt
)
SELECT x.col1,
y.col2,
0 AS cnt
FROM (
SELECT col1 AS col1
FROM @Sample
UNION
SELECT col2
FROM @Sample
) AS x
INNER JOIN (
SELECT col1 AS col2
FROM @Sample
UNION
SELECT col2
FROM @Sample
) AS y ON y.col2 > x.col1
ORDER BY x.col1,
y.col2;
WITH cteSource(col1, col2)
AS (
SELECT CASE
WHEN col1 <= col2 THEN col1
ELSE col2
END AS col1,
CASE
WHEN col1 <= col2 THEN col2
ELSE col1
END AS col2
FROM @Sample
)
UPDATE c
SET c.cnt = w.Items
FROM #Cols AS c
INNER JOIN (
SELECT col1,
col2,
COUNT(*) AS Items
FROM cteSource
GROUP BY col1,
col2
) AS w ON w.col1 = c.col1
AND w.col2 = c.col2;
SELECT col1,
col2,
cnt
FROM #Cols
ORDER BY col1,
col2;
DROP TABLE #Cols;
N 56°04'39.26" E 12°55'05.63" |
 |
|
|
sunitabeck
Flowing Fount of Yak Knowledge
5152 Posts |
Posted - 07/25/2012 : 07:28:48
|
Another way:CREATE TABLE #A (ID INT NOT NULL IDENTITY(1,1), x INT, y INT)
INSERT INTO #A VALUES (1,2),(1,3),(4,2),(1,3);
;WITH Cartesian AS
(
SELECT DISTINCT
a.x,
b.y
FROM
#A a CROSS JOIN #A b
),
Combinations AS
(
SELECT
a.ID,
a.x,
b.y
FROM
#A a INNER JOIN #A b ON
a.ID = B.Id
)
SELECT
a.*,
b.N
FROM
Cartesian a
OUTER APPLY
(
SELECT COUNT(*) AS N FROM
Combinations c
WHERE c.x = a.x AND c.y = a.y
)b;
DROP TABLE #A
|
 |
|
|
KilpAr
Yak Posting Veteran
80 Posts |
Posted - 07/25/2012 : 07:39:45
|
| Thanks to both of you! |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
Sweden
29138 Posts |
Posted - 07/25/2012 : 07:54:40
|
For a combination; isn't {Value1, Value3} then same as {Value3, Value1} ?
N 56°04'39.26" E 12°55'05.63" |
 |
|
|
sunitabeck
Flowing Fount of Yak Knowledge
5152 Posts |
Posted - 07/25/2012 : 08:03:34
|
quote: Originally posted by SwePeso
For a combination; isn't {Value1, Value3} then same as {Value3, Value1} ?
N 56°04'39.26" E 12°55'05.63"
Yes. May be OP actually meant permutations? But not sure because the sample data was such that combinations and permutations yielded the same set. |
 |
|
|
KilpAr
Yak Posting Veteran
80 Posts |
Posted - 08/05/2012 : 09:07:10
|
quote: Originally posted by sunitabeck
quote: Originally posted by SwePeso
For a combination; isn't {Value1, Value3} then same as {Value3, Value1} ?
N 56°04'39.26" E 12°55'05.63"
Yes. May be OP actually meant permutations? But not sure because the sample data was such that combinations and permutations yielded the same set.
Sorry for the late answer. 3,1 is not same than 1,3. The idea is that I have a huge set of values like
Yellow,Blue,Green,Gray,Black Car,Plane,Boat Night,Day,Evening,Morning Left,Right,Up,Down
which I "code" (or "translate to IDs", whatever) to numbers (1,2,3,4,...,N) so
Yellow-Car-Day-Up is 1-1-2-3 and Blue-Car-Evening-Left is 2-1-3-1 which would in SwePeso's idea (or example, whatever) be the same thing, but clearly it is not.
And again, the result I'd want is that there's (in this example) 5*3*4*4 = 240 rows so that I can check against each one that how many of each combinations I have. |
 |
|
| |
Topic  |
|
|
|