2013-11-03 54 views
3

百分比数据我有一个表的用户(它有几百万行)填写表格的用户使用来自另一个表

Id   Name   Country   Product 
+----+---------------+---------------+--------------+ 
    1   John   Canada    
    2   Kate   Argentina     
    3   Mark   China 
    4   Max   Canada 
    5   Sam   Argentina 
    6   Stacy   China   
    ... 
    1000  Ken   Canada 

我想基于百分比与ABC填补Product列。

我有一个名为CountriesStats另一个表像下面

Id  Country   A    B   C 
+-----+---------------+--------------+-------------+----------+ 
    1   Canada   60   20   20 
    2   Argentina  35   45   20 
    3   China   40   10   50 

此表持有人每个产品的百分比。例如在加拿大,60%的人拥有产品A,20%拥有产品B,20%拥有产品C.

我想根据第二个数据中的百分比填充Users表。因此,举例来说,如果有100万个用户在加拿大,我想填写用户表中的列Product 600000与A 200000与B和200000与C

感谢如何做到这一点任何帮助。我不介意在多个步骤中使用它,我只需要提示我如何在SQL中实现这一点。

回答

2

这背后的逻辑并不难。为每个国家的每个人分配一个顺序计数器。然后,使用此值,根据此值分配正确的产品。例如,在你的例子中,当数字小于或等于600,000时,'A'被赋值。 600,001到800,000然后是'B',最后是'C'。

下面的SQL实现这一点:

with toupdate as (
     select u.*, 
      row_number() over (partition by country order by newid()) as seqnum, 
      count(*) over (partition by country) as tot 
     from users u 
    ) 
update u 
    set product = (case when seqnum <= tot * A/100 then 'A' 
         when seqnum <= tot * (A + B)/100 then 'B' 
         else 'C' 
        end) 
    from toupdate u join 
     CountriesStats cs 
     on u.country = cs.country; 

with语句定义可更新的子查询为每个每个国家的序列号和总,每行。这是SQL Server的一个很好的功能,但并不支持所有数据库。

from声明将返回CountriesStats表以获取每个国家/地区的所需值。并且case声明执行必要的逻辑。

请注意,顺序号是随机分配的,使用newid(),所以应该通过初始表随机分配产品。

+0

嗨,谢谢你。我认为这是我正在寻找,但所有我得到的值是'A'我认为它只是检查第一个并根据结果更新整个表。任何想法如何我可以分别更新每行? – Youssef

+0

我做了一些测试,seqnum生成正确,但在更新时,始终为1 – Youssef

+0

@Youssef。 。 。这是非常奇怪的行为。你可以添加一个列到seqnum的大表中,并在那里设置值,使用上面的查询'set = seqnum'? –