Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

range_hashed dictionary layout types

range_hashed

The dictionary is stored in memory in the form of a hash table with an ordered array of ranges and their corresponding values.

This storage method works the same way as hashed and allows using date/time (arbitrary numeric type) ranges in addition to the key.

Example: The table contains discounts for each advertiser in the format:

┌─advertiser_id─┬─discount_start_date─┬─discount_end_date─┬─amount─┐
│           123 │          2015-01-16 │        2015-01-31 │   0.25 │
│           123 │          2015-01-01 │        2015-01-15 │   0.15 │
│           456 │          2015-01-01 │        2015-01-15 │   0.05 │
└───────────────┴─────────────────────┴───────────────────┴────────┘

To use a sample for date ranges, define the range_min and range_max elements in the structure. These elements must contain elements name and type (if type is not specified, the default type will be used - Date). type can be any numeric type (Date / DateTime / UInt64 / Int32 / others).

Example:

CREATE DICTIONARY discounts_dict (
    advertiser_id UInt64,
    discount_start_date Date,
    discount_end_date Date,
    amount Float64
)
PRIMARY KEY id
SOURCE(CLICKHOUSE(TABLE 'discounts'))
LIFETIME(MIN 1 MAX 1000)
LAYOUT(RANGE_HASHED(range_lookup_strategy 'max'))
RANGE(MIN discount_start_date MAX discount_end_date)

To work with these dictionaries, you need to pass an additional argument to the dictGet function, for which a range is selected:

dictGet('dict_name', 'attr_name', id, date)

Query example:

SELECT dictGet('discounts_dict', 'amount', 1, '2022-10-20'::Date);

This function returns the value for the specified ids and the date range that includes the passed date.

Details of the algorithm:

  • If the id is not found or a range is not found for the id, it returns the default value of the attribute’s type.
  • If there are overlapping ranges and range_lookup_strategy=min, it returns a matching range with minimal range_min, if several ranges found, it returns a range with minimal range_max, if again several ranges found (several ranges had the same range_min and range_max it returns a random range of them.
  • If there are overlapping ranges and range_lookup_strategy=max, it returns a matching range with maximal range_min, if several ranges found, it returns a range with maximal range_max, if again several ranges found (several ranges had the same range_min and range_max it returns a random range of them.
  • If the range_max is NULL, the range is open. NULL is treated as maximal possible value. For the range_min 1970-01-01 or 0 (-MAX_INT) can be used as the open value.

Configuration example:

CREATE DICTIONARY somedict(
    Abcdef UInt64,
    StartTimeStamp UInt64,
    EndTimeStamp UInt64,
    XXXType String DEFAULT ''
)
PRIMARY KEY Abcdef
RANGE(MIN StartTimeStamp MAX EndTimeStamp)

Configuration example with overlapping ranges and open ranges:

CREATE TABLE discounts
(
    advertiser_id UInt64,
    discount_start_date Date,
    discount_end_date Nullable(Date),
    amount Float64
)
ENGINE = Memory;

INSERT INTO discounts VALUES (1, '2015-01-01', Null, 0.1);
INSERT INTO discounts VALUES (1, '2015-01-15', Null, 0.2);
INSERT INTO discounts VALUES (2, '2015-01-01', '2015-01-15', 0.3);
INSERT INTO discounts VALUES (2, '2015-01-04', '2015-01-10', 0.4);
INSERT INTO discounts VALUES (3, '1970-01-01', '2015-01-15', 0.5);
INSERT INTO discounts VALUES (3, '1970-01-01', '2015-01-10', 0.6);

SELECT * FROM discounts ORDER BY advertiser_id, discount_start_date;

complex_key_range_hashed

The dictionary is stored in memory in the form of a hash table with an ordered array of ranges and their corresponding values (see range_hashed). This type of storage is for use with composite keys.

Configuration example:

CREATE DICTIONARY range_dictionary
(
  CountryID UInt64,
  CountryKey String,
  StartDate Date,
  EndDate Date,
  Tax Float64 DEFAULT 0.2
)
PRIMARY KEY CountryID, CountryKey
SOURCE(CLICKHOUSE(TABLE 'date_table'))
LIFETIME(MIN 1 MAX 1000)
LAYOUT(COMPLEX_KEY_RANGE_HASHED())
RANGE(MIN StartDate MAX EndDate);
Navigation