谷歌基于groupby

时间:2015-09-21 18:16:21

标签: sql google-bigquery

我想基于groupby随机地移动表的一个列的值。例如,我有两列A和B.现在,我想根据A上的groupby随机地移动B列。

例如,假设A中有三个不同的值。现在,对于A的每个不同值,我想要将B中的值混洗,但只是具有相同A的值。

示例输入:

A       B       C          
-------------------
1       1       x   
1       3       a
2       4       c
3       6       d
1       2       a
3       5       v

示例输出:

A       B       C         
------------------
1       3       x   
1       2       a
2       4       c
3       6       d
1       1       a
3       5       v

在这种情况下,对于A=1,B的值被洗牌。同样的情况发生在A=2,但由于只有一行,它就像它一样。对于A=3,偶然的B值也保持不变。 C列的值保持不变。

也许这可以通过使用窗口函数来解决,但我不确定究竟是怎么回事。

作为旁注:这应该在Google的BigQuery中实现。

2 个答案:

答案 0 :(得分:2)

这是你之后的事吗? (你用Mysql和Oracle标记..所以我在这里用Oracle回答) [edit]根据确认的逻辑进行修正[/ edit]

  with w_data as (
        select 1 a, 1 b from dual union all
        select 1 a, 3 b from dual union all
        select 2 a, 4 b from dual union all
        select 3 a, 6 b from dual union all
        select 1 a, 2 b from dual union all
        select 3 a, 5 b from dual
     ),
     w_suba as (
        select a, row_number() over (partition by a order by dbms_random.value) aid
          from w_data
        ),
     w_subb as (
        select a, b, row_number() over (partition by a order by dbms_random.value) bid
          from w_data
        )
  select sa.a, sb.b
    from w_suba  sa,
         w_subb  sb
   where sa.aid = sb.bid
     and sa.a = sb.a
  /


           A          B
  ---------- ----------
           1          3
           1          1
           1          2
           2          4
           3          6
           3          5

  6 rows selected.

  SQL> /

           A          B
  ---------- ----------
           1          3
           1          1
           1          2
           2          4
           3          5
           3          6

  6 rows selected.

  SQL>

逻辑分解:

1)w_data只是你的样本数据集......

2)随机化列a(不是真的需要,你可以只是rownum这个,然后让b随机...但我喜欢(过)使用dbms_random :)嘿)

3)随机化列b - (使用分区创建"组" ..通过随机排序放大每组中的项目)

4)加入他们......使用组(a)和随机id来查找每个组中的随机项。

通过这种方式随机化你可以确保你得到相同的#..即你从一个" 3" ..你以一个" 3"结束..等等。

答案 1 :(得分:1)

我觉得下面应该可以在BigQuery中使用

SELECT
 x.A as A, x.B as Old_B, x.c as C, y.B as New_B
FROM (
  SELECT A, B, C, 
  ROW_NUMBER() OVER(PARTITION BY A ORDER BY B, C) as pos
  FROM [your_table]
) as x
JOIN (
  SELECT 
    A, B, ROW_NUMBER() OVER(PARTITION BY A ORDER BY rnd) as pos
  FROM (
      SELECT A, B, RAND() as rnd
      FROM [your_table]
  )
) as y
ON x.A = y.A AND x.pos = y.pos