2013-03-04 58 views
1

我有一個名爲'group_quartile'的字段,它使用sql ntile()函數根據他們的活動分數計算每個客戶所處的哪個四分位數。然而,使用這個ntile(0函數,我發現有些客戶的活動分數相同,但分數不同,我需要修改'group-quarterile'列以使所有具有相同活動分數的客戶位於同一個group_quartile中。如何遍歷一個表並在一個字段中查找具有相同值的相鄰行,並在SQL中有條件地更新另一列?

表中的值的視圖:

Customer_id Product Activity_Score Group_Quartile 
CH002   T   2328     1 
CR001   T   268     1 
CN001   T   178     1 
MS006   T   45     2 
ST001   T   21     2 
CH001   T   0     2 
CX001   T   0     3 
KH001   T   0     3 
MH002   T   0     4 
SJ003   T   0     4 
CN001   S   439     1 
AC002   S   177     1 
SC001   S   91     2 
PV001   S   69     3 
TS001   S   0     4 

我用CTE表達,但它因此未工作 我的查詢只更新(從上面的例子):

CX001   T   0     3  

修飾以

CX001   T   0     2 

所以只有第一個重複的活動成績進行檢查和2 我需要更新所有下面的行以及該行的group_quartile被更新。

CX001   T   0     3 
KH001   T   0     3 
MH002   T   0     4 
SJ003   T   0     4 

我不能使用DENSE_RANK(),而不是四分位數來分離記錄在大約4 quartiels安排每個產品的客戶是一個企業的要求。 從我的理解我需要遍歷表 -

  1. 查找具有相同的行爲得分和相同的產品,其前身卻有着不同的group_quartile
  2. 更新選定行的group_quartile其前任的四分一排值
  3. 然後通過已更新的表格查找具有上述條件的任何行,並以相似方式更新該行。
  4. 循環繼續,直到具有相同活動分數(對於同一產品)的所有行放入同一個group_quartile中。

-
這是表結構我的工作:



CREATE TABLE #custs

CUSTOMER_ID NVARCHAR(50),
PRODUCT NVARCHAR(50),
ACTIVITYSCORE INT,
GROUP_QUARTILE INT,
RANKED int,
ROWNUM INT

INSERT INTO #custs
- 添加一列給行號(唯一ID)爲每行
SELECT CUSTOMER_ID,產品,ACTIVITYSCORE,GROUP_QUARTILE,排名,
ROW_NUMBER()OVER (分區由產物ORDER BY activityscore降序)N
FROM
- 基於 '分割' 列值的父表衍生自行
(SELECT CUSTOMER_ID,PRODUCT,aCTIVITYSCORE,
DENSE_RANK()OVER(PARTITION BY PRODUCT ORDER BY ACTIVITYSCORE DESC)AS排名,
NTILE(4)OVER(PARTITION BY PRODUCT ORDER BY ACTIVITYSCORE DESC)AS GROUP_QUARTILE
FROM #parent_score_table WHERE(分割= '大')
)作爲臨時
ORDER BY PRODUCT



我用來實現這一部分是如下的方法:


- 查詢發現其具有活性得分相同,其上一行行,但有一個
不同的GRoup_Quartiel值。
- 我需要使用查詢來更新這一行。
- 接下來,在這個新更新的表中找到任何行,其活動分數與前一行的
相同,但具有不同的group_quartile值。
- 繼續更新上述方式TABEL直到與相同的行爲得分
所有行已經更新,以具有相同的四分位值


我設法找到唯一具有活性的行得分相同,其先前但具有不同的Group_Quartill值,但無法循環查找可能與此更新行匹配的新行。


選擇t1.customer_id,t1.ACTIVITYSCORE,t1.PRODUCT,t1.RANKED,t1.GROUP_QUARTILE,
t2.GROUP_QUARTILE如modified_quartile
從#custs T1,T2 #custs
其中(
T1。 ROWNUM = t2.rownum + 1
和t1.ACTIVITYSCORE = t2.ACTIVITYSCORE
和t1.PRODUCT = t2.PRODUCT
而不是(t1.GROUP_QUARTILE = T2。GROUP_QUARTILE))


任何人都可以幫助什麼應該是上述t-sql語句? 乾杯!

+2

這是什麼RDBMS? SQL Server? – JNK 2013-03-04 16:47:35

+2

也請發佈您的失敗嘗試一些實際的代碼。 – JNK 2013-03-04 16:50:58

+0

SQL Server數據庫。 – Shiny 2013-03-04 16:53:00

回答

1

假設你已經制定了一個基礎Group_Quartile如上所示,你可以用類似下面的查詢更新表:

update a 
set Group_Quartile = coalesce(topq.Group_Quartile, a.Group_Quartile) 
from activityScores a 
    outer apply 
    (
    select top 1 Group_Quartile 
    from activityScores topq 
    where a.Product = topq.Product 
     and a.Activity_Score = topq.Activity_Score 
    order by Group_Quartile 
) topq 

SQL Fiddle with demo。評論後

編輯:

我認爲你做了很多的工作已經得到Group_Quartile工作。

對於表中的每一行,上面的語句將使用outer apply語句將另一行連接到它。由於top 1子句的原因,只有一行將被連接回原始表。

因此,每個行的每一行都返回一行。額外的行將在ProductActivity_Score上匹配,並且將是具有最低的Group_Quartileorder by Group_Quartile)的行。最後,我們用最低的Group_Quartile值更新原始行,因此具有相同ProductActivity_Score的每一行現在將具有相同的最低可能值Group_Quartile

所以SJ003MH002,等等都將被匹配到CH001並用的CH001Group_Quartile值被更新,即。

這很難解釋代碼!另一個可能的幫助是在沒有更新聲明的情況下查看聯接:

select a.* 
    , TopCustomer_id = topq.Customer_Id 
    , NewGroup_Quartile = topq.Group_Quartile 
from activityScores a 
    outer apply 
    (
    select top 1 * 
    from activityScores topq 
    where a.Product = topq.Product 
     and a.Activity_Score = topq.Activity_Score 
    order by Group_Quartile 
) topq 

SQL Fiddle without update

+0

嗨伊恩,偉大的解決方案。有用。你能解釋它是如何工作的嗎? – Shiny 2013-03-05 09:30:13

+0

我已經添加了一些更多的細節;希望他們幫助!原來試圖解釋代碼比編寫代碼更困難。讓我知道我是否可以在此澄清任何事情。 – 2013-03-05 21:36:40

+0

嗨伊恩,你的解釋很有幫助,但說實話,我花了一些時間閱讀代碼,然後再發送解釋並理解邏輯。你說得對,解釋代碼很困難:) – Shiny 2013-03-06 09:44:32

相關問題