【问题标题】:Assign a random order to each group为每个组分配一个随机顺序
【发布时间】:2016-01-09 17:32:24
【问题描述】:

我想将TableA 中的每一行展开为 4 行。结果包含来自TableA 的所有列和另外两个列:SetID = 范围从 0 到 3,并且在按 TableA 分组时是唯一的。 Random = 同一组内SetID 的随机排列。

我使用 SQLite,更喜欢纯 SQL 解决方案。

表 A:

Description
-----------
A
B

期望的输出:

Description | SetID | Random
------------|-------|-------
A           |     0 | 2
A           |     1 | 0
A           |     2 | 3
A           |     3 | 1
B           |     0 | 3
B           |     1 | 2
B           |     2 | 0
B           |     3 | 1

到目前为止,我的尝试解决了为 TableA 中的每一行创建 4 行,但没有正确获得排列。 wrong 将包含一个从 0 到 3 的随机数。对于 Description 中的每个唯一值,我只需要一个 0、1、2 和 3,它们的顺序应该是随机的。

SELECT
  Description,
  SetID,
  abs(random()) % 4 AS wrong
FROM
  TableA
LEFT JOIN
  TableB
ON
  1 = 1

表 B:

SetID
-----
0
1
2
3

【问题讨论】:

  • 要在分组中获得随机但唯一的数字,请参阅前面的post。 OP 通过逐行随机化(存储在临时表中)来回答他自己的问题,但将下一个随机数限制为先前未包含的数字。
  • 感谢其他问题的链接。这可能是解决方案。我会调查的。
  • 顺便说一句,我看你是 R-savy。毫无疑问,您可以导入您的表并在 R 中处理它。请注意:SQL 是一种声明性专用语言,最受DML and DDL 过程的限制。可能不建议超出范围;它不像通用的面向对象语言那样流畅和细致入微:Java、C#、VB、PHP、Python 或 R。
  • 是的,这在 R 中很容易做到。由于表的大小,我正在寻找 SQL 解决方案。

标签: sql sqlite random permutation


【解决方案1】:

考虑一下你的专业解决方案,R。如你所知,R 维护着优秀的数据库包,其中之一是 RSQLite。此外,R 可以通过连接运行命令,而无需导入非常大的数据集。

您的解决方案本质上是无替换的随机抽样。只需让 R 运行采样并将列表项连接到 SQL 字符串中。

下面在 SQLite 数据库中创建一个表,其中 R 将CREATE TABLE 命令发送到 SQL 引擎。没有数据的导入或导出。如果您需要每四行运行一次,请在输出 sql 字符串的已定义函数中运行迭代循环。对于追加查询,请将 CREATE TABLE AS 更改为 INSERT INTO ... SELECT 语句。

library(RSQLite)    

sqlite <- dbDriver("SQLite")
conn <- dbConnect(sqlite,"C:\\Path\\To\\Database\\File\\newexample.db")

# SAMPLE WITHOUT REPLACEMENT
randomnums <- as.list(sample(0:3, 4, replace=F))

# SQL CONCATENATION 
sql <- sprintf("CREATE TABLE PermutationsTable AS 
             SELECT a.Description, b.SetID, 
            (select %d from TableB WHERE TableB.SetID = b.SetID AND TableB.SetID=0
             union select %d from TableB WHERE TableB.SetID = b.SetID AND TableB.SetID=1
             union select %d from TableB WHERE TableB.SetID = b.SetID AND TableB.SetID=2
             union select %d from TableB WHERE TableB.SetID = b.SetID AND TableB.SetID=3) 
             As RandomNumber
             from TableA a, TableB b;",
                  randomnums[[1]], randomnums[[2]],
                  randomnums[[3]], randomnums[[4]])

# RUN QUERY
dbSendQuery(conn, sql)
dbDisconnect(conn)

您会注意到一个嵌套的联合子查询。这用于实现每一行的内联随机数。此外,要从所有表中返回所有可能的组合,不需要连接语句,只需在FROM 子句中列出表即可。

【讨论】:

    【解决方案2】:

    使用cross join

    SELECT Description,
           SetID,
           abs(random()) % 4 AS wrong
    FROM TableA
    CROSS JOIN TableB
    

    【讨论】:

    • 感谢您的提示。但这并不能解决随机排列的问题。
    猜你喜欢
    • 2014-09-28
    • 2020-10-12
    • 2021-03-18
    • 2011-03-28
    • 2019-12-06
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    相关资源
    最近更新 更多