In order to save space for a very particular use-case in Oracle SQL, I'm experimenting with using a bitmap methodology for representing Boolean state over time (an event did or did not happen on that day), with each bit in a binary number representing yes/no for that day. That way, for example, a 32 bit number would allow me to represent 32 consecutive days of whether something happened each day. I would simply need to count the number of bits that are set (=1) to get the count of days in that 32-day period that the event occurred, without having store a separate dated row for each day.
Here's an example of me testing updating the value each day (rolling off the oldest bit and setting the newest one):
SELECT testbitmap original_bitmap,
BITAND((testbitmap * POWER(2,/*rolloff the nbr of days since last event*/1)) + /*the event happened today*/1,POWER(2,32)-1) new_bitmap
FROM (SELECT BIN_TO_NUM(1,1,0,0,1,1,0,0,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0) testbitmap
FROM dual)
So far so good. But now I need to query the result, and that means counting the set bits of my resulting bitmap. There isn't an inverse of BIN_TO_NUM
that I know of in Oracle. Without using a function that loops through each bit and tests it individually, is there a way to count set bits in Oracle (e.g. the number 9 should result in 2 (1001
), whereas the number 7 would result in 3 (0111
)? Maybe a mathematical formula the returns the number of 1s required to represent a number in binary?