我正在尝试根据CTE的值更新表中的数据。我遇到了几个问题,目前SQL Server说它找不到列名WeightedRating而我真的不知道为什么..或者它是什么谈论。
目前我正在尝试的是在CTE上混合使用MERGE关键字。
这是我的完整查询:
DECLARE @COUNT_VALUE FLOAT -- MINIMUM OF VOTES REQUIRED TO BE LISTED IN THE TOP
DECLARE @minimumVotesRequired FLOAT -- MINIMUM OF VOTES REQUIRED TO BE LISTED IN THE TOP
SET @minimumVotesRequired = 3
;WITH CTE_2 (SumOfVoteScore,CountOfVotes,IdProduct)
AS
(
SELECT
SUM(r.Stars) AS SumOfVoteScore, -- THIS IS THE SUMMATORY OF ALL THE STARS THAT WERE GIVEN TO THE PRODUCT
COUNT(rap.IdProduct) AS CountOfVotes, --HOW MANY RATINGS OF PRODUCTS WHERE MADE, this is the vote count
rap.IdProduct
FROM
glamstapp.Rating AS r INNER JOIN glamstapp.RatingAndProducts AS rap ON r.IdRating = rap.IdRating
GROUP BY
rap.IdProduct
)
,CTE_3 (idProduct,vote_count,vote_mean1,vote_mean2)
AS
(
SELECT CONVERT(FLOAT,rap.IdProduct) as IdProduct,
--ISNULL(CTE_2.SumOfVoteScore,0) AS vote_sum,
CONVERT(FLOAT,CTE_2.CountOfVotes) AS vote_count,
COALESCE((CONVERT(FLOAT,CTE_2.SumOfVoteScore)/ (CONVERT(FLOAT,CTE_2.CountOfVotes))),0) AS vote_mean1, --THE MEAN OF EACH PRODUCT
COALESCE((CONVERT(FLOAT,CTE_2.SumOfVoteScore)/ (CONVERT(FLOAT,CTE_2.CountOfVotes))),0) AS vote_mean2
FROM glamstapp.RatingAndProducts AS rap INNER JOIN CTE_2 ON rap.idProduct = CTE_2.idProduct
GROUP BY rap.IdProduct,
CTE_2.SumOfVoteScore,
CTE_2.CountOfVotes
)
MERGE INTO glamstapp.RatingAndProducts
USING
(
SELECT CTE_3.idProduct,(CONVERT(FLOAT,CTE_3.vote_count) / (CONVERT(FLOAT,CTE_3.vote_count) + @minimumVotesRequired))
* CONVERT(FLOAT,CTE_3.vote_mean1) +
(@minimumVotesRequired / (CONVERT(FLOAT,CTE_3.vote_count)+ @minimumVotesRequired))
* (SUM(CONVERT(FLOAT,CTE_3.vote_mean2))/(select count (CTE_3.vote_mean2) from CTE_3)) AS WeightedRating
FROM CTE_3
GROUP BY
CTE_3.vote_count,
CTE_3.IdProduct,
CTE_3.vote_mean1
)
AS Source
ON glamstapp.RatingAndProducts.idProduct = source.idProduct
WHEN MATCHED THEN
UPDATE SET glamstapp.RatingAndProducts.WeightedRating = //<--The error is present in here or so SQL Server points out when I double click on the error.
source.WeightedRating ;;
答案 0 :(得分:1)
将glamstapp.RatingAndProducts.WeightedRating
更改为WeightedRating
。您不需要通过数据库名称或表来限定名称,因为merge语句只能影响单个已经明确声明的表,事实上,我相信即使是两到四个部分名称,我相信在UPDATE和MERGE声明。有关语法,请参阅MERGE (Transact-SQL),相关部分为:
[ WITH <common_table_expression> [,...n] ]
MERGE
[ TOP ( expression ) [ PERCENT ] ]
[ INTO ] <target_table> [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ]
USING <table_source>
ON <merge_search_condition>
[ WHEN MATCHED [ AND <clause_search_condition> ]
THEN <merge_matched> ] [ ...n ]
[ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]
THEN <merge_not_matched> ]
[ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]
THEN <merge_matched> ] [ ...n ]
[ <output_clause> ]
[ OPTION ( <query_hint> [ ,...n ] ) ]
;
那么<merge_matched>
的定义是什么?
<merge_matched>::=
{ UPDATE SET <set_clause> | DELETE }
好的,那么什么是<set_clause>
?
<set_clause>::=
SET
{ column_name = { expression | DEFAULT | NULL }
| { udt_column_name.{ { property_name = expression
| field_name = expression }
| method_name ( argument [ ,...n ] ) }
}
| column_name { .WRITE ( expression , @Offset , @Length ) }
| @variable = expression
| @variable = column = expression
| column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
| @variable { += | -= | *= | /= | %= | &= | ^= | |= } expression
| @variable = column { += | -= | *= | /= | %= | &= | ^= | |= } expression
} [ ,...n ]
需要注意的重要一点是语法结构使用column_name
而不是<column_name>
,后者可以用多部分名称指定:
<column_name> ::=
{ DELETED | INSERTED | from_table_name } . { * | column_name }
| $action
同样,这里的摘要和关键是当使用MERGE
语句时,目标表已经明确指定,因此您不需要在SET的左侧使用多部分名称表达式,语法实际上禁止这样做,因为只有一个有效的表名,一个有效的数据库名,一个有效的服务器名,用于SET表达式的每个部分的左侧。