SQLite每组需要N行

时间:2018-02-19 14:55:29

标签: sqlite random limit-per-group

我有一个类似于以下内容的SQLite表:

| A | B |
_________
| e | 5 |
| f | 7 |
| a | 5 |
| n | 7 |
| g | 5 |
| d | 7 |
| i | 5 |
| j | 5 |
| e | 7 |
| v | 7 |

如何检索列5中值为B的三个随机行和值为7的三个随机行?我不知道B中的值,5 ad 7值。 我希望B中的每个不同值有3个随机行。结果可能不会按列B值进行分组。它可能是这样的:

| A | B |
_________
| e | 5 |
| g | 5 |
| e | 7 |
| v | 7 |
| j | 5 |
| f | 7 |

2 个答案:

答案 0 :(得分:1)

以下几乎可以满足您的需求:

select t.*
from t
where t.rowid in (select t2.rowid
                  from t t2
                  where t2.b = t.b
                  order by random()
                  limit 3
                 );

唉,子查询将为每一行运行,所以这只是近似值,因为随机数生成器会在每次执行时更改值。

一种解决方案是使用临时表来存储每行的随机数,然后可以将其用于排序。不幸的是,CTE似乎没有做到这一点,因为这些都是在每个参考文献上重新评估的。

经过一番思考,我认为临时表可能是唯一的解决方案:

drop table if exists tempt;

create temporary table tempt as 
    select t.*, random() as rand
    from t;

select t.*
from tempt t
where t.rowid in (select t2.rowid
                  from tempt t2
                  where t2.b = t.b
                  order by rand
                  limit 3
                 );

答案 1 :(得分:1)

您可以使用隐藏的RowID列为每个B值获取三行,如下所示:

 SELECT A, B FROM T T1
    WHERE RowID IN (SELECT RowID FROM T T2 WHERE B = T1.B LIMIT 3);

请注意,您很可能(但不是100%保证)每次都能获得相同的三行。如果你想以牺牲一些性能为代价来获取随机行,你可以这样做:

 SELECT A, B FROM T T1
    WHERE RowID IN (SELECT RowID FROM T T2 WHERE B = T1.B ORDER BY random() LIMIT 3);