2017-02-17 3 views
1

나는 고객을위한 개별 등급이있는 테이블이 있습니다. 일부 고객에게는 상위 고객이 있습니다. 나는이 표에 모든 고객을 나열하는보기를 작성하려고합니다. 등급 (및 자녀가있는 경우 자녀)과 등급 (자녀가있는 경우 자녀의 등급)의 평균을 표시합니다.). 재귀 쿼리에 대해 머리 숙이고 CLOSE가되었지만 부모 (parent) ID에 이상한 문제가 있습니다. 부모와 자식의 수 (또는 자녀) 또는 참 (true) 수를 정확하게 반영하지 않습니다. 자녀들의 평점 평균.MS SQL 2008 집계 문제 상위 - 하위 롤업

예를 들어 SqlFiddle http://sqlfiddle.com/#!3/a6c1d/2을 참조하십시오. 내가 기대하는 바는 18639에 ratingCount가 13 개 (나머지 고객의 부모가 됨)이지만 내 쿼리가이를 반환하지 않는다는 것입니다.

아이디어가 있으십니까? 이 개 고객 관련에서 구성되는 CTE에 대한 쿼리와 함께,

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ConsumerRating]') AND type in (N'U')) 
    DROP TABLE [dbo].[ConsumerRating] 
    GO 

    IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ConsumerRatingCustomer]') AND type in (N'U')) 
    DROP TABLE [dbo].[ConsumerRatingCustomer] 
    GO 


    CREATE TABLE [dbo].[ConsumerRatingCustomer](
     [cust_id] [int] NOT NULL, 
     [cust_rating_id] [varchar](50) NOT NULL, 
     [image_name] [varchar](50) NULL, 
     [about] [varchar](500) NULL, 
     [Parent_Cust_Id] [int] NULL, 
    CONSTRAINT [PK_ConsumerRatingCustomer] PRIMARY KEY CLUSTERED 
    (
     [cust_id] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY] 
    ) ON [PRIMARY] 
    GO 

    CREATE TABLE [dbo].[ConsumerRating](
     [consumer_rating_id] [int] IDENTITY(1,1) NOT NULL, 
     [rate_quote_id] [int] NOT NULL, 
     [cust_id] [int] NOT NULL, 
     [rating] [int] NOT NULL, 
    CONSTRAINT [PK_ConsumerRating] PRIMARY KEY CLUSTERED 
    (
     [consumer_rating_id] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY] 
    ) ON [PRIMARY] 
    GO 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (18639, N'186391st', NULL, NULL, NULL) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (32887, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (33236, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (33515, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34470, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34489, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34587, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34588, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34710, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34934, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34935, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34936, N'186391st', NULL, NULL, 18639) 
    INSERT [dbo].[ConsumerRatingCustomer] ([cust_id], [cust_rating_id], [image_name], [about], [Parent_Cust_Id]) VALUES (34937, N'186391st', NULL, NULL, 18639) 

    SET IDENTITY_INSERT [dbo].[ConsumerRating] ON 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (2068, 6845810, 18639, 5) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (2168, 6345810, 18639, 5) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (1599, 6494148, 32887, 7) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (1788, 6630226, 33236, 4) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (4034, 8726778, 33515, 10) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (4846, 9206561, 34470, 3) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (4635, 9051031, 34489, 9) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (4317, 8874479, 34587, 5) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (4258, 8839973, 34588, 6) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (4658, 9061441, 34710, 7) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (4844, 9206340, 34937, 8) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (1844, 9106340, 34937, 8) 
    INSERT [dbo].[ConsumerRating] ([consumer_rating_id], [rate_quote_id], [cust_id], [rating]) VALUES (2844, 9006340, 34937, 8) 
    SET IDENTITY_INSERT [dbo].[ConsumerRating] OFF 

내가 재귀 쿼리를 사용하고 있습니다 : SQLFIDDLE를 사용하지 않는 분들을 위해

, 여기 출발점으로 데이터입니다 테이블 (부모/자식 관계와 한 세트로 등급을 얻을 수 있습니다.

 with ratings as 
    (
    SELECT  
    consumer_rating_id, 
    rate_quote_id, 
    c.cust_id, 
    rating,  
    c.cust_rating_id, 
    c.parent_cust_id 
    FROM ConsumerRating cr 
    join ConsumerRatingCustomer c ON cr.cust_id = C.cust_id 
    ) 
    , RollupCTE(cust_id, parent_cust_id, rating) 
    AS 
    (
    Select cust_id, parent_cust_id, rating From ratings 
    Union All 
    Select A.cust_id, A.parent_cust_id, T.rating From ratings A 
    Inner Join RollupCTE T On A.cust_id = T.parent_cust_id 
    ) 

    Select cust_id, count(rating) as ratingCount,avg(rating) as ratingAverage From RollupCTE 

    Group By cust_id 
    order by cust_id 

문제는 내 부모 행이 올바른 집계 표시되지 않는 것입니다.

cust_id ratingCount ratingAverage 
    18639 24 6 
    32887 1 7 
    33236 1 4 
    33515 1 10 
    34470 1 3 
    34489 1 9 
    34587 1 5 
    34588 1 6 
    34710 1 7 
    34937 3 8 

나는 "뚜렷한"어딘가 또는 어리석은 뭔가를 놓치고 있다는 것을 알고있다. 누구든지이 문제에 경험이 있습니까?

답변

0

은 첫 번째 CTE는 고객 테이블과 등급에 가입하여 시작합니다

SELECT  
consumer_rating_id, 
rate_quote_id, 
c.cust_id, 
rating,  
c.cust_rating_id, 
c.parent_cust_id 
FROM ConsumerRating cr 
join ConsumerRatingCustomer c ON cr.cust_id = C.cust_id 

그냥 위의 쿼리의 결과를 보면, 당신은 이미 두 개의 최상위 고객 (18639) 및 기타 (11)가 각 고객과 관련이있는 고객은 "24"의 합계가 (2 + 11 + 11)에서 비롯됩니다. 따라서 최종 계층을 구축 할 수는 없습니다.

은 먼저 계층 구조의 "폐쇄"테이블을 구축해야하고 당신의 등급 테이블이 조인

;with CustomerRelations as (
    Select cust_id, cust_id as Parent_cust_Id 
    From ConsumerRatingCustomer 
    Union All 
    Select c2.cust_id, c2.parent_cust_id 
    From CustomerRelations c 
     join ConsumerRatingCustomer c2 On c.cust_id = c2.parent_cust_id 
) 
select cr.Parent_cust_Id, count(*) as count, AVG(cast(rating as float)) as AvgRating 
from [ConsumerRating] r 
     join CustomerRelations cr on r.cust_id = cr.cust_id 
group by Parent_cust_Id; 

Parent_cust_Id count  AvgRating 
-------------- ----------- ---------------------- 
18639   13   6.53846153846154 
32887   1   7 
33236   1   4 
33515   1   10 
34470   1   3 
34489   1   9 
34587   1   5 
34588   1   6 
34710   1   7 
34937   3   8 
+0

예,이 작품 -이의 "루트"를 찾는 어려움을 겪고 있었다 재귀 쿼리 - 클로저 테이블은 내가 찾고자했던 집합 기반 솔루션입니다. 호기심에서, 웹에 언급 된이 "폐쇄 표"방법은 어디에 있습니까? 꽤 좋은 googler 인 것에 자부심을 느끼지만, 당신과 비슷한 예를 찾을 수 없습니다. –

+0

"계층 구조 폐쇄 테이블"을 봤는데 많은 링크가 나타났습니다. 예를 들면 다음과 같습니다. http://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html SQL Server 2008 이상에서 "hierarchyId"데이터 유형을 조사 할 수 있습니다 , 쉽게 모든 ID를 얻을 수 있습니다. –

+0

감사합니다. 부모 - 자식 집계 및 관련 용어를 검색하고 있었고 "폐쇄"용어가 없었습니다. –