我有一张表,对客户有个别评级。有些客户有父母客户。我试图在这张桌子上写一个视图,列出所有客户,他们的评分数(以及他们的孩子,如果他们有孩子),以及他们的评分平均值(以及他们的孩子,如果他们有孩子)。我在递归查询时已经敲了敲头,并且已经接近了,但我和父母一起遇到了这个奇怪的问题" ids,他们不能准确反映他们(及其子女)的评分数或他们(以及他们的孩子)评级的真实平均值。
有关示例,请参阅SqlFiddle http://sqlfiddle.com/#!3/a6c1d/2。我期望18639的ratingCount为13(作为其他客户的父母),但我的查询不会返回。
有什么想法吗?
对于那些不使用SQLFIDDLE的人,以数据为起点:
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
我使用递归查询,查询由两个与客户相关的表构建的cte(将父/子关系和评级合并为一组。
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
我知道我错过了一个" distinct"某处或某种愚蠢的东西。有没有人有过这个问题的经验?
答案 0 :(得分: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