根据 groupby 在 Google 的 BigQuery 中随机排列列
Shuffle column in Google's BigQuery based on groupby
我想根据 groupby 随机打乱 table 的单个列的值。例如,我有两列 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 列的值保持不变。
也许这可以通过使用 window 函数来解决,但我不确定具体如何。
附带说明:这应该在 Google 的 BigQuery 中实现。
这就是你想要的吗? (您同时标记了 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 -(使用分区分析创建 "groups" ..随机排序随机化每个组中的项目)
4) 加入他们...使用组 (a) 和随机 ID 在每个组中找到一个随机项目。
通过这种方式进行随机化,您可以确保获得相同的#..即您以一个“3”开始..您以一个“3”结束..等等
我觉得下面应该在 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
我想根据 groupby 随机打乱 table 的单个列的值。例如,我有两列 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 列的值保持不变。
也许这可以通过使用 window 函数来解决,但我不确定具体如何。
附带说明:这应该在 Google 的 BigQuery 中实现。
这就是你想要的吗? (您同时标记了 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 -(使用分区分析创建 "groups" ..随机排序随机化每个组中的项目)
4) 加入他们...使用组 (a) 和随机 ID 在每个组中找到一个随机项目。
通过这种方式进行随机化,您可以确保获得相同的#..即您以一个“3”开始..您以一个“3”结束..等等
我觉得下面应该在 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