Author |
Topic |
maxim
Yak Posting Veteran
51 Posts |
Posted - 2007-09-13 : 13:13:34
|
I have a problem!I have my categories table with:CategoryID, ParentID, NameAnd my articles table: ArticleID, CategoryID, Name.... etc.I need to select "CategoryID, CategoryName, ArticlesCount""articlescount" Should represent the count for all articles in this category and the count for all articles in childs categorysI tried but I don't know how can i build my query! :(Thanks,Max |
|
X002548
Not Just a Number
15586 Posts |
|
maxim
Yak Posting Veteran
51 Posts |
Posted - 2007-09-13 : 14:39:42
|
No... That query only show the article count for each category.I want cumulative count!I tried your example:CREATE TABLE Categories(ID int, Name varchar(50), ParentID int)CREATE TABLE Articles(ID int, Name varchar(50), CategoryID int)INSERT INTO [Categories] ([Name],[ParentID]) VALUES (C1, 0)INSERT INTO [Categories] ([Name],[ParentID]) VALUES (C2, 1)INSERT INTO [Categories] ([Name],[ParentID]) VALUES (C3, 1)INSERT INTO [Categories] ([Name],[ParentID]) VALUES (C4, 3)INSERT INTO [Categories] ([Name],[ParentID]) VALUES (C5, 3)INSERT INTO [Articles] ([Name],[CategoryID]) VALUES (A1, 3)INSERT INTO [Articles] ([Name],[CategoryID]) VALUES (A2, 3)INSERT INTO [Articles] ([Name],[CategoryID]) VALUES (A3, 5)INSERT INTO [Articles] ([Name],[CategoryID]) VALUES (A4, 5)INSERT INTO [Articles] ([Name],[CategoryID]) VALUES (A5, 5)INSERT INTO [Articles] ([Name],[CategoryID]) VALUES (A6, 4)INSERT INTO [Articles] ([Name],[CategoryID]) VALUES (A7, 4)INSERT INTO [Articles] ([Name],[CategoryID]) VALUES (A8, 4)SELECT c.ID, COUNT(*) FROM Categories c JOIN Articles a ON c.ID = a.CategoryID GROUP by c.ID With this string that you gave me i select:ID - Count3 - 24 - 35 - 3But I want to select cumulative count, like:ID - Count3 - 84 - 35 - 3The next image demonstrate the structure:category3 (c3) has 8 articles! Not 2 as your query return!If anyone could help me i'll appreciate |
|
|
X002548
Not Just a Number
15586 Posts |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-09-13 : 14:46:54
|
[code]DECLARE @Sample TABLE (ID INT, ParentID INT, Name VARCHAR(100), Amount MONEY)INSERT @SampleSELECT 7, NULL, 'Ljunggren', 1000 UNION ALLSELECT 3, 1, 'Gulli', 200 UNION ALLSELECT 8, 7, 'Kerstin', 45 UNION ALLSELECT 1, NULL, 'Rosberg', 1 UNION ALLSELECT 4, 2, 'Peter', 222 UNION ALLSELECT 5, 3, 'Susanne', 111 UNION ALLSELECT 2, 1, 'Jan-Eric', 59 UNION ALLSELECT 10, 9, 'Jennie', 2000 UNION ALLSELECT 6, 3, 'Annelie', 666 UNION ALLSELECT 9, 7, 'Kenneth', 100 UNION ALLSELECT 11, 9, 'Jessica', 199;WITH Yak (Level, ID, ParentID, Name, Amount)AS ( SELECT 0, s1.ID, s1.ParentID, s1.Name, s1.Amount FROM @Sample AS s1 LEFT JOIN @Sample AS s2 ON s2.ParentID = s1.ID WHERE s2.ID IS NULL UNION ALL SELECT y.Level + 1, s.ID, s.ParentID, s.Name, s.Amount + y.Amount FROM Yak AS y INNER JOIN @Sample AS s ON s.ID = y.ParentID)SELECT ID, Name, SUM(Amount) AS AmountFROM YakGROUP BY ID, ParentID, NameORDER BY ID, ParentID, Name[/code] E 12°55'05.25"N 56°04'39.16" |
|
|
X002548
Not Just a Number
15586 Posts |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-09-13 : 14:57:07
|
Nope. Not within walking distance anyway. E 12°55'05.25"N 56°04'39.16" |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-09-13 : 15:18:26
|
Better versionDECLARE @Sample TABLE (ID INT, ParentID INT, Name VARCHAR(100), Amount INT)INSERT @SampleSELECT 7, NULL, 'Ljunggren', 200 UNION ALLSELECT 3, 1, 'Gulli', 199 UNION ALLSELECT 8, 7, 'Kerstin', 23 UNION ALLSELECT 1, NULL, 'Rosberg', 145 UNION ALLSELECT 4, 2, 'Peter', 222 UNION ALLSELECT 5, 3, 'Susanne', 333 UNION ALLSELECT 2, 1, 'Jan-Eric', 234 UNION ALLSELECT 10, 9, 'Jennie', 333 UNION ALLSELECT 6, 3, 'Annelie', 666 UNION ALLSELECT 9, 7, 'Kenneth', 1200 UNION ALLSELECT 11, 9, 'Jessica', 69;WITH Yak (ID, ParentID, Name, Path, Indent, Amount)AS ( SELECT ID, ParentID, Name, CONVERT(VARCHAR, ROW_NUMBER() OVER (ORDER BY Name)), 0, Amount FROM @Sample WHERE ParentID IS NULL UNION ALL SELECT s.ID, s.ParentID, s.Name, CONVERT(VARCHAR, y.Path + '.' + CONVERT(VARCHAR, ROW_NUMBER() OVER (ORDER BY s.Name DESC))), y.Indent + 1, s.Amount FROM @Sample AS s INNER JOIN Yak AS y ON y.ID = s.ParentID)SELECT y1.ID, y1.ParentID, REPLICATE('.....', y1.Indent) + y1.Name AS Name, y1.Path, y1.Amount, SUM(y2.Amount) AS TotAmountFROM Yak AS y1INNER JOIN Yak AS y2 ON y2.Path LIKE y1.Path + '%'GROUP BY y1.ID, y1.ParentID, REPLICATE('.....', y1.Indent) + y1.Name, y1.Amount, y1.PathORDER BY y1.Path E 12°55'05.25"N 56°04'39.16" |
|
|
maxim
Yak Posting Veteran
51 Posts |
Posted - 2007-09-13 : 16:01:44
|
Peso, you should delete your first script...I tested and i was here trying to understand why did he return wrong cumulative sum's...Thanks for posting version 2! This work!But i have one question (forgive me)I have two tables.Categories(with parentcategoryid) and articles.I need to select all categories(with articlescount from articlesTable) into one tempTable and only then run your procedure right? |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-09-13 : 16:07:09
|
Or, with the concept of JOIN, you can add the second column directly in the CTE. E 12°55'05.25"N 56°04'39.16" |
|
|
maxim
Yak Posting Veteran
51 Posts |
Posted - 2007-09-13 : 16:35:23
|
Thanks Very much Peso! I'm glad that you had time for this. I searched in this forum and i found many post asking for this without answers !I'm going to have 2 tables:Declare @Categories TABLE (CategoryID int IDENTITY(1,1), Name varchar(50), ParentID int)Declare @Articles TABLE (ArticleID int IDENTITY(1,1), Name varchar(50), CategoryID int)INSERT INTO @Categories ([Name],[ParentID]) VALUES ('C1', 0)INSERT INTO @Categories ([Name],[ParentID]) VALUES ('C2', 1)INSERT INTO @Categories ([Name],[ParentID]) VALUES ('C3', 1)INSERT INTO @Categories ([Name],[ParentID]) VALUES ('C4', 3)INSERT INTO @Categories ([Name],[ParentID]) VALUES ('C5', 3)INSERT INTO @Articles ([Name],[CategoryID]) VALUES ('A1', 3)INSERT INTO @Articles ([Name],[CategoryID]) VALUES ('A2', 3)INSERT INTO @Articles ([Name],[CategoryID]) VALUES ('A3', 5)INSERT INTO @Articles ([Name],[CategoryID]) VALUES ('A4', 5)INSERT INTO @Articles ([Name],[CategoryID]) VALUES ('A5', 5)INSERT INTO @Articles ([Name],[CategoryID]) VALUES ('A6', 4)INSERT INTO @Articles ([Name],[CategoryID]) VALUES ('A7', 4)INSERT INTO @Articles ([Name],[CategoryID]) VALUES ('A8', 4)DECLARE @Sample TABLE (ID INT, ParentID INT, Name VARCHAR(50), ArticlesCount INT)INSERT @SampleSELECT CategoryID, ParentID, Name, (SELECT COUNT(*) FROM @Articles AS a WHERE a.categoryID = c.CategoryID) As ArticlesCount FROM @Categories AS c ORDER BY Name ASC;WITH Yak (ID, ParentID, Name, Path, Indent, ArticlesCount)AS ( SELECT ID, ParentID, Name, CONVERT(VARCHAR, ROW_NUMBER() OVER (ORDER BY Name)), 0, ArticlesCount FROM @Sample WHERE ParentID = 0 --IS NULL UNION ALL SELECT s.ID, s.ParentID, s.Name, CONVERT(VARCHAR, y.Path + '.' + CONVERT(VARCHAR, ROW_NUMBER() OVER (ORDER BY s.Name DESC))), y.Indent + 1, s.ArticlesCount FROM @Sample AS s INNER JOIN Yak AS y ON y.ID = s.ParentID)SELECT y1.ID, y1.ParentID, REPLICATE('.....', y1.Indent) + y1.Name AS Name, y1.Path, y1.ArticlesCount, SUM(y2.ArticlesCount) AS TotArticlesFROM Yak AS y1INNER JOIN Yak AS y2 ON y2.Path LIKE y1.Path + '%'GROUP BY y1.ID, y1.ParentID, REPLICATE('.....', y1.Indent) + y1.Name, y1.ArticlesCount, y1.PathORDER BY y1.Path I want this for articles and categories, but I need to upgrade my asp.net forum with subforums...I'm thinking about use this code!When user enter in forum, the parent forums need to show all posts Cumulative count.But i have more than thousands of posts... Is this a good solution for that? Thanks very much! |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-09-13 : 17:05:57
|
[code]-- Prepare sample dataDECLARE @Categories TABLE (CategoryID INT, Name VARCHAR(50), ParentID INT)INSERT @Categories (CategoryID, Name, ParentID) VALUES (1, 'C1', 0)INSERT @Categories (CategoryID, Name, ParentID) VALUES (2, 'C2', 1)INSERT @Categories (CategoryID, Name, ParentID) VALUES (3, 'C3', 1)INSERT @Categories (CategoryID, Name, ParentID) VALUES (4, 'C4', 3)INSERT @Categories (CategoryID, Name, ParentID) VALUES (5, 'C5', 3)DECLARE @Articles TABLE (ArticleID INT, Name VARCHAR(50), CategoryID INT)INSERT @Articles (ArticleID, Name, CategoryID) VALUES (1, 'A1', 3)INSERT @Articles (ArticleID, Name, CategoryID) VALUES (2, 'A2', 3)INSERT @Articles (ArticleID, Name, CategoryID) VALUES (3, 'A3', 5)INSERT @Articles (ArticleID, Name, CategoryID) VALUES (4, 'A4', 5)INSERT @Articles (ArticleID, Name, CategoryID) VALUES (5, 'A5', 5)INSERT @Articles (ArticleID, Name, CategoryID) VALUES (6, 'A6', 4)INSERT @Articles (ArticleID, Name, CategoryID) VALUES (7, 'A7', 4)INSERT @Articles (ArticleID, Name, CategoryID) VALUES (8, 'A8', 4)-- Stage some data;WITH Yak (CategoryID, Name, ParentID, Articles)AS ( SELECT c.CategoryID, c.Name, c.ParentID, COUNT(a.ArticleID) FROM @Categories AS c LEFT JOIN @Articles AS a ON a.CategoryID = c.CategoryID GROUP BY c.CategoryID, c.Name, c.ParentID), Yak2 (CategoryID, Name, ParentID, Articles, Path)AS ( SELECT CategoryID, Name, ParentID, Articles, CONVERT(VARCHAR, ROW_NUMBER() OVER (ORDER BY CategoryID)) FROM Yak WHERE ParentID = 0 UNION ALL SELECT y.CategoryID, y.Name, y.ParentID, y.Articles, CONVERT(VARCHAR, y2.Path + '.' + CONVERT(VARCHAR, ROW_NUMBER() OVER (ORDER BY y.CategoryID))) FROM Yak AS y INNER JOIN Yak2 AS y2 ON y2.CategoryID = y.ParentID)-- Show the expected outputSELECT y1.CategoryID, y1.Name, y1.Path, y1.Articles, SUM(y2.Articles) AS TotArticlesFROM Yak2 AS y1INNER JOIN Yak2 AS y2 ON y2.Path LIKE y1.Path + '%'GROUP BY y1.CategoryID, y1.Name, y1.Path, y1.ArticlesORDER BY y1.Path[/code] E 12°55'05.25"N 56°04'39.16" |
|
|
maxim
Yak Posting Veteran
51 Posts |
Posted - 2007-09-13 : 18:13:53
|
:) Thanks Peso! I had hope that you could rectify the original code! Thanks a lot.My ability is asp.net... I use sql for the basic stuff. But I'm concerned with rapid queries... I'll use this script to select my forums and one-level sub-forums too!Max,Portugal |
|
|
|
|
|