1

我有一个表,其中有一个名为“group_quartile”的字段,它使用 sql ntile() 函数根据他们的活动分数计算每个客户所在的四分位数。但是使用这个 ntile(0 函数我发现有一些客户具有相同的活动分数但在不同的四分位数。我需要修改'group-quartile'列以使具有相同活动分数的所有客户都位于同一个 group_quartile。

表值的视图:

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

所以只检查第一个重复活动分数,并且该行的 group_quartile 更新为 2。我还需要更新以下所有行。

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

我不能使用 DENSE_RANK() 而不是四分位数来分隔记录,因为将每个产品的客户安排在大约 4 个四分位数中是一项业务要求。据我了解,我需要遍历表格 -

  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, PRODUCT, ACTIVITYSCORE,GROUP_QUARTILE,RANKED,
Row_Number() OVER(partition by product ORDER BY activityscore desc) N
FROM
-- 基于“细分”列值从父表派生的行
(SELECT customer_id, PRODUCT, ACTIVITYSCORE,
DENSE_RANK( ) 超过(按产品顺序按 ActivitySCORE DESC 划分)排名,
NTILE(4) OVER(PARTITION BY PRODUCT ORDER BY ACTIVITYSCORE DESC) AS GROUP_QUARTILE
FROM #parent_score_table WHERE (SEGMENTATION = 'Large')
) as temp
ORDER BY PRODUCT



我用来部分实现此目的的方法如下:


-- 查询查找活动分数与其前一行相同但具有
不同 GRoup_Quartiel 值的行。
-- 我需要使用查询来更新这一行。
-- 接下来,在这个新更新的表中查找活动分数与其
前一行相同但具有不同 group_quartile 值的任何行。
-- 继续以上述方式更新表格,直到所有具有相同活动分数的行
都已更新为具有相同的四分位数


我设法仅找到活动分数与其前一行相同但具有不同 Group_Quartill 值的行但是无法循环查找可能与此更新行匹配的新行。


选择 t1.customer_id,t1.ACTIVITYSCORE,t1.PRODUCT, t1.RANKED, t1.GROUP_QUARTILE,
t2.GROUP_QUARTILE as modified_quartile
from #custs t1, #custs t2
where (
t1.rownum = t2.rownum + 1
and t1.ACTIVITYSCORE = t2.ACTIVITYSCORE
和 t1.PRODUCT = t2.PRODUCT
而不是(t1.GROUP_QUARTILE = t2.GROUP_QUARTILE))


任何人都可以帮助解决上述的 t-sql 语句吗?干杯!

4

1 回答 1

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 与演示

评论后编辑:

我认为你已经通过工作完成了很多Group_Quartile工作。

对于表中的每一行,上面的语句将使用该outer apply语句连接另一行。top 1由于该子句,只有一行将连接回原始表。

因此,对于每一行,我们将再返回一行。额外的行将在Product和上匹配Activity_Score,并且将是具有最低Group_Quartile( order by Group_Quartile) 的行。最后,我们用这个最低值更新原始行,Group_Quartile因此每一行都具有相同的值ProductActivity_Score现在将具有相同的最低值Group_Quartile

所以SJ003MH002 等都将匹配到CH001并更新为CH001Group_Quartile的值,即2

代码很难解释!另一件可能有帮助的事情是在没有更新语句的情况下查看连接:

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 没有更新

于 2013-03-04T17:26:05.517 回答