?
Solved

T-SQL Query needed for double-level string concatination from a single table

Posted on 2010-11-09
14
Medium Priority
?
235 Views
Last Modified: 2012-05-10
For Microsoft SQL Server 2005 T-SQL I'm having difficulty writing a query that concatenates two-levels such as Compact Disc discs and tracks (see table below).

My best attempt is using XML as a vehicle for string concatenation as described here.

Using a single query without a server-side cursor I'd like to generate a report of my music collection like below with one concatenated line output per database row per album.  Once I figure out the query I'll add the appropriate HTML as a detail.

OUTPUT ROW 1:

Album 1
  Disc 1
    1. She Loves You
    2. Yellow Submarine

  Disc 2
    1. Revolution
    2. Long and Winding Road
    3. Hey Jude


OUTPUT ROW 2:

Album 2
  Disc 1
    ...


OUTPUT ROW 3:

Album 3
  Disc 1
     ....

  Disc 2
    .....
create table Song (
  AlbumID int,
  DiscNbr tinyint,
  TrackNbr tinyint,
  Song varchar(50)
)

Open in new window

0
Comment
Question by:ZuZuPetals
[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
  • 7
  • 5
  • 2
14 Comments
 
LVL 3

Expert Comment

by:expert_dharam
ID: 34095404
Did u tried this..

select AlbumID, STUFF(
      (SELECT  ',' + a.Song  AS [text()]
      from Song  a
      where a.AlbumID = b.AlbumID
      Order by a.Song
      for xml PATH('')),1,1,''      ) AS Comments_Concatenated
 from Song b
group by AlbumID
ORDER BY AlbumID
0
 
LVL 2

Author Comment

by:ZuZuPetals
ID: 34095689
Yes, but that's one level.
0
 
LVL 3

Expert Comment

by:expert_dharam
ID: 34095933
Here you go..

SELECT AlbumID, DiscNbr,

STUFF(
      (SELECT  ', ' + cast(a.TrackNbr as varchar) + '.' + a.Song  AS [text()]
      FROM Song  a
      WHERE a.AlbumID = b.AlbumID and a.DiscNbr = b.DiscNbr
      Order by a.Song
      FOR XML PATH('')),1,1,''      ) AS Songs
      
      
 FROM Song b
group by AlbumID,DiscNbr
ORDER BY AlbumID,DiscNbr
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Author Comment

by:ZuZuPetals
ID: 34097195
Thanks expert_dharam... that's a partial solution: that creates one row per disc.    Now I'm trying to caress it to roll up all discs of an album to a single row.
0
 
LVL 51

Expert Comment

by:Mark Wills
ID: 34099464
How about something like :


select ',' + 'Album '+convert(varchar,a.albumid) + ',' +
       'Disc '+convert(varchar,a.Discnbr) +
       (select ',' + convert(varchar,Tracknbr) + '.' + Song
        from song b where a.albumid = b.albumid and a.discnbr = b.discnbr for xml path('')) as [text()]
from (select distinct albumid, Discnbr from song) a  
for xml path('')
0
 
LVL 51

Expert Comment

by:Mark Wills
ID: 34099476
Think I might be misunderstanding your output requirement... Treated it as one long concatenated string.

Thats not quite what you are after - is it...

0
 
LVL 51

Expert Comment

by:Mark Wills
ID: 34099553
What about....


select listing
from (
      select albumid,0 as discnbr, 0 as tracknbr, 'Album '+convert(varchar,albumid) as listing from song group by albumid
      union
      select albumid,discnbr, 0 as tracknbr, '     Disc '+convert(varchar,Discnbr) as listing from song group by albumid, discnbr
      union
      select albumid,discnbr, tracknbr, '          '+convert(varchar,tracknbr)+'. '+song as listing from song
     )s
order by albumid,discnbr, tracknbr


0
 
LVL 2

Author Comment

by:ZuZuPetals
ID: 34105602
@mark_wills: The first one concatenates to a single string and the second one does no concatenation.  Still looking for something in between (one row per album), but I appreciate the attempts.
0
 
LVL 51

Expert Comment

by:Mark Wills
ID: 34106926
Right, knew I was misunderstanding :D

how about :

select 'Album '+convert(varchar,a.albumid) +
       (select ','+'Disc '+convert(varchar,Discnbr) +',' + convert(varchar,Tracknbr) + '.' + Song
        from song b where a.albumid = b.albumid for xml path('')) as [text()]
from (select distinct albumid from song) a  
0
 
LVL 2

Author Comment

by:ZuZuPetals
ID: 34113510
@mark_willis: Wow, that's really close.  The only bad thing is that it repeats the disc number for every track.
0
 
LVL 2

Author Comment

by:ZuZuPetals
ID: 34113560
My solution that I implemented is to use XML/text() to encapsulate the "tracks per disc" concatenation into a view for simplicity and readability.  I then use that view in a second XML/text() to concatenate the "discs per album" into a single string.  It takes 10 minutes to run on a million records but produces the exact result specified in the problem statement.  Thanks for everyone's help.
0
 
LVL 51

Accepted Solution

by:
Mark Wills earned 2000 total points
ID: 34113837
Ah well... Good to hear you got your solution...

FWIW here is my last attempt (it is a challenge now) :)


select 'Album '+convert(varchar,a.albumid) +
    (select ','+'Disc '+convert(varchar,D.Discnbr) +
        (select ',' + convert(varchar,Tracknbr) + '.' + Song from song b where a.albumid = b.albumid and d.Discnbr=b.Discnbr for xml path(''))
    from song d where a.albumid=d.albumid group by d.discnbr for xml path(''))
from (select distinct albumid from song) a
0
 
LVL 2

Author Comment

by:ZuZuPetals
ID: 34114895
Awesome!!! That's it!  You did it Mark!  Thanks!

The only thing I added was order by DiscNbr,TrackNbr to get the ordering 1, 2, 3, etc. ascending.
0
 
LVL 2

Author Closing Comment

by:ZuZuPetals
ID: 34114898
YOU ROCK!
0

Featured Post

Want to be a Web Developer? Get Certified Today!

Enroll in the Certified Web Development Professional course package to learn HTML, Javascript, and PHP. Build a solid foundation to work toward your dream job!

Question has a verified solution.

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

If you find yourself in this situation “I have used SELECT DISTINCT but I’m getting duplicates” then I'm sorry to say you are using the wrong SQL technique as it only does one thing which is: produces whole rows that are unique. If the results you a…
I'm trying, I really am. But I've seen so many wrong approaches involving date(time) boundaries I despair about my inability to explain it. I've seen quite a few recently that define a non-leap year as 364 days, or 366 days and the list goes on. …
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…

764 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