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.
Author |
Topic |
Harry C
Posting Yak Master
148 Posts |
Posted - 2008-04-30 : 01:01:45
|
My categories table is as follows categoryid, CategoryName, ParentID, DateAddedI have data that looks like the following from this SQLSELECT * from categories ORDER By CategoryName, ParentID32 Automotive 0 2008-04-08 13:23:24.44039 Bartending 0 2008-04-08 13:24:11.97045 test 32 2008-04-29 17:24:22.64033 The dressing room 0 2008-04-08 13:23:32.550What I would like is to Order this by CategoryName, but whenever the category has sub categories, I would like them to appear beneath it like so32 Automotive 0 2008-04-08 13:23:24.44045 test 32 2008-04-29 17:24:22.64039 Bartending 0 2008-04-08 13:24:11.97033 The dressing room 0 2008-04-08 13:23:32.550I am sure this is easy, but I am just missing it. Any thoughts? |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-04-30 : 04:37:45
|
[code]DECLARE @temp table(categoryid int,CategoryName varchar(50), ParentID int,DateAdded datetime)INSERT INTO @tempSELECT 32, 'Automotive', 0, '2008-04-08 13:23:24.440'UNION ALLSELECT 39, 'Bartending', 0, '2008-04-08 13:24:11.970'UNION ALLSELECT 45, 'test', 32, '2008-04-29 17:24:22.640'UNION ALLSELECT 33, 'The dressing room', 0, '2008-04-08 13:23:32.550'UNION ALLSELECT 47, 'xcvsd', 39, '2008-04-08 13:23:32.550'UNION ALLSELECT 49, 'sdvfdbg', 33, '2008-04-08 13:23:32.550'UNION ALLSELECT 53, 'vbgr', 39, '2008-04-08 13:23:32.550'UNION ALLSELECT 65, 'ert', 0, '2008-04-08 13:23:32.550'UNION ALLSELECT 77, 'cvxnbvng', 32, '2008-04-08 13:23:32.550'SELECT t.categoryid,t.CategoryName,t.ParentID,t.DateAddedFROM(SELECT t1.*, COALESCE(t2.CategoryName,t1.CategoryName) AS SortOrderFROM @temp t1LEFT JOIN @temp t2ON t2.categoryid=t1.ParentID)tORDER BY t.SortOrder,t.ParentIDoutput-----------------------------------------------------------categoryid CategoryName ParentID DateAdded----------- -------------------------------------------------- ----------- -----------------------32 Automotive 0 2008-04-08 13:23:24.44045 test 32 2008-04-29 17:24:22.64077 cvxnbvng 32 2008-04-08 13:23:32.55039 Bartending 0 2008-04-08 13:24:11.97047 xcvsd 39 2008-04-08 13:23:32.55053 vbgr 39 2008-04-08 13:23:32.55065 ert 0 2008-04-08 13:23:32.55033 The dressing room 0 2008-04-08 13:23:32.55049 sdvfdbg 33 2008-04-08 13:23:32.550[/code] |
 |
|
RyanRandall
Master Smack Fu Yak Hacker
1074 Posts |
Posted - 2008-04-30 : 06:06:56
|
Hi HarryAnother option I sometimes prefer when dealing with hierarchical data like this is to create a function which returns the 'path' of ancestors. You can then use that path in various ways - one of which is sorting. Here's an example...-- Structure and dataCREATE TABLE MyCategories (CategoryId int primary key, CategoryName varchar(50), ParentId int, DateAdded datetime)INSERT INTO MyCategories SELECT 32, 'Automotive', 0, '2008-04-08 13:23:24.440'UNION ALL SELECT 39, 'Bartending', 0, '2008-04-08 13:24:11.970'UNION ALL SELECT 45, 'test', 32, '2008-04-29 17:24:22.640'UNION ALL SELECT 33, 'The dressing room', 0, '2008-04-08 13:23:32.550'UNION ALL SELECT 47, 'xcvsd', 39, '2008-04-08 13:23:32.550'UNION ALL SELECT 49, 'sdvfdbg', 33, '2008-04-08 13:23:32.550'UNION ALL SELECT 53, 'vbgr', 39, '2008-04-08 13:23:32.550'UNION ALL SELECT 65, 'ert', 0, '2008-04-08 13:23:32.550'UNION ALL SELECT 77, 'cvxnbvng', 45, '2008-04-08 13:23:32.550'go-- Functioncreate function dbo.AncestorPath(@CategoryId int) returns varchar(100) asbegin declare @Path varchar(100) while 0 = 0 begin select @Path = cast(CategoryId as varchar(5)) + isnull('/' + @Path, ''), @CategoryId = ParentId from dbo.MyCategories where CategoryId = @CategoryId if @@rowcount = 0 break end return @Pathendgo-- Calculationselect * from (select *, isnull(dbo.AncestorPath(ParentId) + '/', '') + cast(CategoryId as varchar(10)) as Path from MyCategories) aorder by Path/* ResultsCategoryId CategoryName ParentId DateAdded Path----------- ---------------------- ----------- ----------------------- -----------------32 Automotive 0 2008-04-08 13:23:24.440 3245 test 32 2008-04-29 17:24:22.640 32/4577 cvxnbvng 45 2008-04-08 13:23:32.550 32/45/7733 The dressing room 0 2008-04-08 13:23:32.550 3349 sdvfdbg 33 2008-04-08 13:23:32.550 33/4939 Bartending 0 2008-04-08 13:24:11.970 3947 xcvsd 39 2008-04-08 13:23:32.550 39/4753 vbgr 39 2008-04-08 13:23:32.550 39/5365 ert 0 2008-04-08 13:23:32.550 65*/ There's another example here...http://www.sqlteam.com/Forums/topic.asp?TOPIC_ID=101053Ryan Randall Solutions are easy. Understanding the problem, now, that's the hard part. |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-04-30 : 06:25:07
|
Using Ryan's sample data, try a recursive CTE;WITH Yak (CategoryID, ParentID, Path, categoryname, dateadded)AS ( SELECT CategoryID, ParentID, CAST(CategoryID AS VARCHAR(max)), categoryname, dateadded FROM MyCategories WHERE ParentID = 0 union all select c.categoryid, c.parentid, y.path + '/' + cast(c.categoryid as varchar(max)), c.categoryname, c.dateadded from mycategories as c inner join yak as y on y.categoryid = c.parentid)select categoryid, categoryname, parentid, dateadded, pathfrom yakorder by Path E 12°55'05.25"N 56°04'39.16" |
 |
|
Harry C
Posting Yak Master
148 Posts |
Posted - 2008-04-30 : 08:22:51
|
wow, thank you to all three of you. Very much appreciated. Glad I asked though, it was hardly as "easy" as I was trying to make it. |
 |
|
|
|
|
|
|