Reputation: 41
First let me say that pivot solutions are good, but in this case can't be the final solution because the result is several empty columns (for values which don't match a particular record) and this can't be used on MS Access 2010 reports.
I believe this is common problem and a good solution would help many small developers who are just starting their adventure into VBA for Access.
Suppose I have table in Ms Access with following information:
| ProductID | AssignedColour |
|-----------|----------------|
| 1 | white |
| 1 | red |
| 1 | yellow |
| 2 | black |
| 2 | white |
| 3 | pink |
The problem is that in the table there are around 10,000 products which use around 250 unique color names (and list of colors can increase). Also, one particular ProductID might have assigned to it an undefined number of colors.
My question is: How can I present all assigned colors in one row but have the color names split into separate columns?
The query results I want are as follows:
| ProductID | Colour1 | Colour2 | Colour3 | .... as many Columns as |
| | | | | assigned in above table. |
|-----------|---------|---------|---------|-------------------------------|
| 1 | white | red | yellow | |
| 2 | black | white | | |
| 3 | pink | | | |
I need to generate MS Access 2010 reports and present every product with only assigned colors (empty columns are not allowed).
I found some solutions based on pivot tables, but this results in 250 dynamically created columns. So I don't know how can I show only specific columns with only colors matching for a particular product.
My solution gives the results as follows:
| ProductID | Colour1 | Colour2 | Colour3 | .... 250 columns with colors, |
| | | | | but it can't be on reports.|
|-----------|---------|---------|---------|---------------------------------|
| 1 | white | red | yellow | |
| 2 | white | <empty> | <empty> | |
| 3 | <empty> | <empty> | <empty> | |
MS Access does not allow for the presentation of dynamic columns. Also generating such reports takes very long time. It gives empty fields, something that is unacceptable on professional reports. I am considering if I should put query values into some temporary table first and then concatenate the values, but I don't know how to make that table. Maybe somebody has a sample database which could cover all of these aspects.
Upvotes: 4
Views: 2586
Reputation: 1
Try this
SELECT t.Filed1,
STUFF(ISNULL((SELECT ', ' + x.Filed2
FROM TableName x
WHERE x.Filed1= t.Filed1
GROUP BY x.Filed2
FOR XML PATH (''), TYPE).value('.','VARCHAR(max)'), ''), 1, 2, '')
FROM TableName t
GROUP BY t.Filed1
Upvotes: 0
Reputation: 123779
Start by creating a query that assigns a ranked name to each colour by ProductID
SELECT
t1.ProductID,
t1.AssignedColour,
"Colour" & Format(COUNT(*),"000") AS ColourName
FROM
ProductColours AS t1
INNER JOIN
ProductColours AS t2
ON t1.ProductID = t2.ProductID
AND t1.AssignedColour >= t2.AssignedColour
GROUP BY
t1.ProductID,
t1.AssignedColour
returning
ProductID AssignedColour ColourName
--------- -------------- ----------
1 red Colour001
1 white Colour002
1 yellow Colour003
2 black Colour001
2 white Colour002
3 pink Colour001
Now wrap that in a crosstab query to PIVOT on ColourName
TRANSFORM First(AssignedColour) AS whatever
SELECT
ProductID
FROM
(
SELECT
t1.ProductID,
t1.AssignedColour,
"Colour" & Format(COUNT(*),"000") AS ColourName
FROM
ProductColours AS t1
INNER JOIN
ProductColours AS t2
ON t1.ProductID = t2.ProductID
AND t1.AssignedColour >= t2.AssignedColour
GROUP BY
t1.ProductID,
t1.AssignedColour
) AS ColourNames
GROUP BY ProductID
PIVOT ColourName
which returns
ProductID Colour001 Colour002 Colour003
--------- --------- --------- ---------
1 red white yellow
2 black white
3 pink
Upvotes: 5