Sets of yes-or-no options are often stored compactly as bits of one integer: 1 for snacks, 2 for a hot meal, 4 for a bar, 8 for Wi-Fi. BIT_AND_AGG, BIT_OR_AGG, and BIT_XOR_AGG combine such integers over a group, bit by bit, to answer questions like "which services are on every flight" in one aggregate.
Code for This Guide
The main examples are in the examples/aggregate-functions folder of the Oracle Database 26ai code repository on GitHub, each with its output. They use NIMBUS, the sample schema of a fictional airline, which you can install with the scripts in the setup/nimbus folder.
They come from Oracle Database 26ai SQL and PL/SQL Book.
Syntax
Syntax:
bit_and_agg(expr) bit_or_agg(expr) bit_xor_agg(expr)
| Function | Keeps a bit when it is set in |
|---|---|
| BIT_AND_AGG | Every value |
| BIT_OR_AGG | At least one value |
| BIT_XOR_AGG | An odd number of values |
Combine Service Flags
Four flights have the flags 3, 7, 15, and 11.
Example:
-- service flags per route: 1 = snacks, 2 = hot meal, 4 = bar, 8 = Wi-Fi
select bit_and_agg(flags) as on_every_flight,
bit_or_agg(flags) as on_some_flight,
bit_xor_agg(flags) as xor
from (values (3), (7), (15), (11)) t (flags);Output:
ON_EVERY_FLIGHT ON_SOME_FLIGHT XOR
__________________ _________________ ______
3 15 03 is snacks plus hot meal, which every flight has, so BIT_AND_AGG returns 3. BIT_OR_AGG returns 15: every service is on some flight. Each bit is set an even number of times, so BIT_XOR_AGG returns 0.
Read the Flags with BITAND
BITAND tests single bits within one value, which shows what the flags mean.
Example:
-- decode the flags with BITAND: 1 = snacks, 2 = hot meal, 4 = bar, 8 = Wi-Fi
select flags,
case when bitand(flags, 1) > 0 then 'Y' end as snacks,
case when bitand(flags, 2) > 0 then 'Y' end as hot_meal,
case when bitand(flags, 4) > 0 then 'Y' end as bar,
case when bitand(flags, 8) > 0 then 'Y' end as wifi
from (values (3), (7), (15), (11)) t (flags);Output:
FLAGS SNACKS HOT_MEAL BAR WIFI
________ _________ ___________ ______ _______
3 Y Y
7 Y Y Y
15 Y Y Y Y
11 Y Y YSnacks and the hot meal appear on all four flights, matching BIT_AND_AGG's 3.
Things to Know
- The values must be integers; NULLs are ignored.
- BIT_XOR_AGG is useful as a quick, order-independent fingerprint of a set of integers.
- For readability in new designs, separate BOOLEAN columns are easier to query than packed bits; bit aggregates shine with existing flag columns and compact storage.
Related Guides
Conclusion
BIT_AND_AGG keeps the bits set in every value of a group, BIT_OR_AGG those set in any, and BIT_XOR_AGG those set an odd number of times. Use them with flag integers to find common and available options across rows, and BITAND to decode single bits.
