Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Need help with crosstable

Author  Topic 

mikjon
Starting Member

2 Posts

Posted - 2005-04-08 : 04:38:40
Hello, I need help with a crosstable. My tables looks like this:

ACCESSORIES
MACHINE_OBJ_NO
ACC_NO
ARTICLE_OBJ_NO

ARTICLE
OBJ_NO
ARTICLE_DESCRIPTION

MACHINE
OBJ_NO
MACHINE_NO

Every machine_obj_no in the accessories-table have one or several rows = ARTICLE_OBJ_NO.
I want a crosstable which shows all the machines in the the accessories-table, one row for each machine.
On the same row i want all the ARTICLE_OBJ_NO-rows for this machine show up as columns.

I want this result (example):
MACHINE_NO1 ACC1 ACC2 NULL NULL
MACHINE_NO2 ACC1 ACC2 ACC3 ACC4
MACHINE_NO3 ACC1 NULL NULL NULL
MACHINE_NO4 ACC1 ACC2 ACC3 NULL
...
where ACC1 is the ARTICLE_DESCRIPTION for the first ARTICLE_OBJ_NO in the ACCESSORIES-table, and so on...
Thankful for tips and help.

mwjdavidson
Aged Yak Warrior

735 Posts

Posted - 2005-04-12 : 06:39:40
Hi
I'm assuming that you want all articles associated with each machine as contiguous columns with any NULL values appearing at the end. As such, you need an ordinal position to use when 'unfolding' this data. I've added this to a derived table, but this would probably be done in a view or added to your underlying table.
You could get away without this if your columns represented specific articles, in which case you would replace "CASE WHEN acc.ORDINAL_POS = ..." with "CASE WHEN acc.ARTICLE_OBJ_NO = ..."



SELECT
MACHINE_NO,
MAX(CASE WHEN acc.ORDINAL_POS = 1 THEN art.ARTICLE_DESCRIPTION ELSE NULL END) AS '1',
MAX(CASE WHEN acc.ORDINAL_POS = 2 THEN art.ARTICLE_DESCRIPTION ELSE NULL END) AS '2',
MAX(CASE WHEN acc.ORDINAL_POS = 3 THEN art.ARTICLE_DESCRIPTION ELSE NULL END) AS '3',
MAX(CASE WHEN acc.ORDINAL_POS = 4 THEN art.ARTICLE_DESCRIPTION ELSE NULL END) AS '4'/*,
etc.
*/
FROM
(
SELECT
acc.MACHINE_OBJ_NO,
acc.ACC_NO,
acc.ARTICLE_OBJ_NO,
(
SELECT
COUNT(*) + 1
FROM
ACCESSORIES AS acc2
WHERE
acc2.MACHINE_OBJ_NO = acc.MACHINE_OBJ_NO
and acc2.ARTICLE_OBJ_NO < acc.ARTICLE_OBJ_NO
) AS ORDINAL_POS
FROM ACCESSORIES AS acc
) AS acc

JOIN dbo.MACHINE AS m
ON acc.MACHINE_OBJ_NO = m.OBJ_NO
JOIN dbo.ARTICLE AS art
ON acc.ARTICLE_OBJ_NO = art.OBJ_NO
GROUP BY
m.MACHINE_NO
ORDER BY
m.MACHINE_NO



Mark
Go to Top of Page

mikjon
Starting Member

2 Posts

Posted - 2005-04-12 : 09:57:38
Hello Mark,

Thank You very much! Just cut & paste... Done! Marvelous!
I will just complete it all with a view as You suggested.
You have saved me hours of "trial and error".

Again: Thanks!
/Mikael
Go to Top of Page

mwjdavidson
Aged Yak Warrior

735 Posts

Posted - 2005-04-12 : 10:46:24
Glad I could help!

Mark
Go to Top of Page
   

- Advertisement -