2013-07-15 49 views
0

我想基於一個CTE的值更新表中的數據..我有幾個問題,目前SQL Server說,它找不到列名稱WeightedRating,我真的不知道爲什麼..或什麼它在說什麼。如何從CTE中獲取的值進行更新? - SQL Server

目前我正在嘗試的是沿着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 ;; 

回答

1

變化glamstapp.RatingAndProducts.WeightedRating只是WeightedRating。您不需要通過數據庫名稱或表格限定名稱,因爲合併語句只能影響單個已經明確聲明的表格,事實上,我相信甚至有兩至四個部分名稱我相信在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表達式每個部分左側的一個有效服務器名稱。