Roaring bitmaps for calculating retention
CREATE TABLE test_roaring_bitmap
ENGINE = MergeTree
ORDER BY h AS
SELECT
intDiv(number, 5) AS h,
groupArray(toUInt16(number - (2 * intDiv(number, 5)))) AS vals,
groupBitmapState(toUInt16(number - (2 * intDiv(number, 5)))) AS vals_bitmap
FROM numbers(40)
GROUP BY h
SELECT
h,
vals,
hex(vals_bitmap)
FROM test_roaring_bitmap
┌─h─┬─vals─────────────┬─hex(vals_bitmap)─────────┐
│ 0 │ [0,1,2,3,4] │ 000500000100020003000400 │
│ 1 │ [3,4,5,6,7] │ 000503000400050006000700 │
│ 2 │ [6,7,8,9,10] │ 000506000700080009000A00 │
│ 3 │ [9,10,11,12,13] │ 000509000A000B000C000D00 │
│ 4 │ [12,13,14,15,16] │ 00050C000D000E000F001000 │
│ 5 │ [15,16,17,18,19] │ 00050F001000110012001300 │
│ 6 │ [18,19,20,21,22] │ 000512001300140015001600 │
│ 7 │ [21,22,23,24,25] │ 000515001600170018001900 │
└───┴──────────────────┴──────────────────────────┘
SELECT
groupBitmapAnd(vals_bitmap) AS uniq,
bitmapToArray(groupBitmapAndState(vals_bitmap)) AS vals
FROM test_roaring_bitmap
WHERE h IN (0, 1)
┌─uniq─┬─vals──┐
│ 2 │ [3,4] │
└──────┴───────┘
See also A primer on roaring bitmaps