SQL 到 select 随机插入的分组结果
SQL to select randomly intercalated grouped results
对于具有 ID 和类别列的 table,我们将有一个包含 5 个值的类别域,例如 A、B、C、D 和 E。
我们正在使用 SQLite。
我们的目标是有一个查询,该查询带来许多随机选择和随机排序的插入分组行(在每组 5 行内),例如
ID CAT
--- ---
076 C
753 D
503 A
081 B
335 E
475 B
643 D
995 A
105 E
549 C
553 E
871 B
064 C
720 D
119 A
上面的示例显示了 3 组 os 结果,whose 行是随机选择的,whose 排序也是随机的。
目前我们正在使用 5 个查询(每个类别一个)提取结果,然后根据应用程序代码对所有内容进行排序。
SELECT * FROM table WHERE cat = 'A' ORDER BY RANDOM() LIMIT 3;
如果有人通过使用单个查询提出更好的解决方案,我们将不胜感激。
您可以将以下查询与 3 个并集一起使用,它不是很短,但它确实有效:
SELECT randomized.id, randomized.cat
FROM (
SELECT randomized.id, randomized.cat
FROM (
SELECT id,cat FROM `table_test` ORDER BY RANDOM()
) AS randomized
GROUP BY cat
ORDER BY RANDOM()
) AS randomized
UNION ALL
SELECT randomized.id, randomized.cat
FROM (
SELECT randomized.id, randomized.cat
FROM (
SELECT id,cat FROM `table_test` ORDER BY RANDOM()
) AS randomized
GROUP BY cat
ORDER BY RANDOM()
) AS randomized
UNION ALL
SELECT randomized.id, randomized.cat
FROM (
SELECT randomized.id, randomized.cat
FROM (
SELECT id,cat FROM `table_test` ORDER BY RANDOM()
) AS randomized
GROUP BY cat
ORDER BY RANDOM()
) AS randomized
您可以使用五个临时表为每个类别中的行分配 autoincrementing ID:
CREATE TEMPORARY TABLE a(nr INTEGER PRIMARY KEY, id);
CREATE TEMPORARY TABLE b(nr INTEGER PRIMARY KEY, id);
...
INSERT INTO temp.a(id) SELECT id FROM MyTable WHERE cat = 'A' ORDER BY random();
INSERT INTO temp.b(id) SELECT id FROM MyTable WHERE cat = 'B' ORDER BY random();
...
然后可以把五个表合并起来,让nr
值相同的行排在一起:
SELECT nr, id, 'A' AS cat, random() AS r FROM temp.a
UNION ALL
SELECT nr, id, 'B', random() FROM temp.b
UNION ALL
...
ORDER BY nr, r;
开发了一种方法来获得我们需要的结果:连续的行块,每个块没有 'cat' 重复,并且根本没有 'id' 重复。
它更偏向于数学而不是面向查询,但无论如何它适合我们的需要。
CREATE TEMPORARY TABLE a(nr INTEGER PRIMARY KEY, sort, id, cat);
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'A' ORDER BY random() limit 3;
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'B' ORDER BY random() limit 3;
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'C' ORDER BY random() limit 3;
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'D' ORDER BY random() limit 3;
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'E' ORDER BY random() limit 3;
UPDATE temp.a SET sort=100 where nr=1;
UPDATE temp.a SET sort=92+(select abs(random()%(2))*16) where nr=4;
UPDATE temp.a SET sort=88+(select abs(random()%(4))*8) where nr=7;
UPDATE temp.a SET sort=86+(select abs(random()%(8))*4) where nr=10;
UPDATE temp.a SET sort=85+(select abs(random()%(16))*2) where nr=13;
UPDATE temp.a SET sort=200 where nr=2;
UPDATE temp.a SET sort=192+(select abs(random()%(2))*16) where nr=5;
UPDATE temp.a SET sort=188+(select abs(random()%(4))*8) where nr=8;
UPDATE temp.a SET sort=186+(select abs(random()%(8))*4) where nr=11;
UPDATE temp.a SET sort=185+(select abs(random()%(16))*2) where nr=14;
UPDATE temp.a SET sort=300 where nr=3;
UPDATE temp.a SET sort=292+(select abs(random()%(2))*16) where nr=6;
UPDATE temp.a SET sort=288+(select abs(random()%(4))*8) where nr=9;
UPDATE temp.a SET sort=286+(select abs(random()%(8))*4) where nr=12;
UPDATE temp.a SET sort=285+(select abs(random()%(16))*2) where nr=15;
SELECT id, cat FROM temp.a ORDER BY sort;
DROP TABLE a;
对于具有 ID 和类别列的 table,我们将有一个包含 5 个值的类别域,例如 A、B、C、D 和 E。
我们正在使用 SQLite。
我们的目标是有一个查询,该查询带来许多随机选择和随机排序的插入分组行(在每组 5 行内),例如
ID CAT --- --- 076 C 753 D 503 A 081 B 335 E 475 B 643 D 995 A 105 E 549 C 553 E 871 B 064 C 720 D 119 A
上面的示例显示了 3 组 os 结果,whose 行是随机选择的,whose 排序也是随机的。
目前我们正在使用 5 个查询(每个类别一个)提取结果,然后根据应用程序代码对所有内容进行排序。
SELECT * FROM table WHERE cat = 'A' ORDER BY RANDOM() LIMIT 3;
如果有人通过使用单个查询提出更好的解决方案,我们将不胜感激。
您可以将以下查询与 3 个并集一起使用,它不是很短,但它确实有效:
SELECT randomized.id, randomized.cat
FROM (
SELECT randomized.id, randomized.cat
FROM (
SELECT id,cat FROM `table_test` ORDER BY RANDOM()
) AS randomized
GROUP BY cat
ORDER BY RANDOM()
) AS randomized
UNION ALL
SELECT randomized.id, randomized.cat
FROM (
SELECT randomized.id, randomized.cat
FROM (
SELECT id,cat FROM `table_test` ORDER BY RANDOM()
) AS randomized
GROUP BY cat
ORDER BY RANDOM()
) AS randomized
UNION ALL
SELECT randomized.id, randomized.cat
FROM (
SELECT randomized.id, randomized.cat
FROM (
SELECT id,cat FROM `table_test` ORDER BY RANDOM()
) AS randomized
GROUP BY cat
ORDER BY RANDOM()
) AS randomized
您可以使用五个临时表为每个类别中的行分配 autoincrementing ID:
CREATE TEMPORARY TABLE a(nr INTEGER PRIMARY KEY, id);
CREATE TEMPORARY TABLE b(nr INTEGER PRIMARY KEY, id);
...
INSERT INTO temp.a(id) SELECT id FROM MyTable WHERE cat = 'A' ORDER BY random();
INSERT INTO temp.b(id) SELECT id FROM MyTable WHERE cat = 'B' ORDER BY random();
...
然后可以把五个表合并起来,让nr
值相同的行排在一起:
SELECT nr, id, 'A' AS cat, random() AS r FROM temp.a
UNION ALL
SELECT nr, id, 'B', random() FROM temp.b
UNION ALL
...
ORDER BY nr, r;
开发了一种方法来获得我们需要的结果:连续的行块,每个块没有 'cat' 重复,并且根本没有 'id' 重复。
它更偏向于数学而不是面向查询,但无论如何它适合我们的需要。
CREATE TEMPORARY TABLE a(nr INTEGER PRIMARY KEY, sort, id, cat);
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'A' ORDER BY random() limit 3;
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'B' ORDER BY random() limit 3;
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'C' ORDER BY random() limit 3;
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'D' ORDER BY random() limit 3;
INSERT INTO temp.a(id, cat) SELECT id, cat FROM tabela WHERE cat = 'E' ORDER BY random() limit 3;
UPDATE temp.a SET sort=100 where nr=1;
UPDATE temp.a SET sort=92+(select abs(random()%(2))*16) where nr=4;
UPDATE temp.a SET sort=88+(select abs(random()%(4))*8) where nr=7;
UPDATE temp.a SET sort=86+(select abs(random()%(8))*4) where nr=10;
UPDATE temp.a SET sort=85+(select abs(random()%(16))*2) where nr=13;
UPDATE temp.a SET sort=200 where nr=2;
UPDATE temp.a SET sort=192+(select abs(random()%(2))*16) where nr=5;
UPDATE temp.a SET sort=188+(select abs(random()%(4))*8) where nr=8;
UPDATE temp.a SET sort=186+(select abs(random()%(8))*4) where nr=11;
UPDATE temp.a SET sort=185+(select abs(random()%(16))*2) where nr=14;
UPDATE temp.a SET sort=300 where nr=3;
UPDATE temp.a SET sort=292+(select abs(random()%(2))*16) where nr=6;
UPDATE temp.a SET sort=288+(select abs(random()%(4))*8) where nr=9;
UPDATE temp.a SET sort=286+(select abs(random()%(8))*4) where nr=12;
UPDATE temp.a SET sort=285+(select abs(random()%(16))*2) where nr=15;
SELECT id, cat FROM temp.a ORDER BY sort;
DROP TABLE a;