Skip to content
9.12 JSON Columns and Queries

9.12 JSON Columns and Queries

This section covers LOOKUP JSON column support and JSON predicate queries.

LOOKUP JSON Predicate Queries

LOOKUP supports JSON for ordinary columns. Use JSON columns to store flexible attributes alongside reference data.

CREATE LOOKUP TABLE ch9_json (
    sensor_id VARCHAR(80) PRIMARY KEY,
    location  VARCHAR(200),
    config    JSON
);

INSERT INTO ch9_json VALUES (
    'TEMP-01',
    'factory1',
    '{"unit":"celsius","level":3,"threshold":{"high":90.0}}'
);

SELECT sensor_id, config
FROM ch9_json
WHERE config->'$.unit' = 'celsius';

Type-Specific JSON Predicates

Use type-specific JSON extraction functions to compare numeric values as numbers.

SELECT sensor_id
FROM ch9_json
WHERE JSON_EXTRACT_INTEGER(config, '$.level') >= 3
  AND JSON_EXTRACT_DOUBLE(config, '$.threshold.high') > 80.0;

You can also inspect the JSON structure itself.

SELECT sensor_id
FROM ch9_json
WHERE JSON_IS_VALID(config) = 1
  AND JSON_TYPEOF(config, '$.threshold') = 'Object';

PRIMARY KEY Restriction

LOOKUP can store JSON columns, but JSON cannot be a PRIMARY KEY. Use a stable ordinary type such as INTEGER, LONG, or VARCHAR for row identifiers.

-- Expected failure: JSON cannot be a primary key.
CREATE LOOKUP TABLE ch9_json_bad (
    config JSON PRIMARY KEY,
    note   VARCHAR(80)
);
-- Recommended: use a separate identifier as the primary key.
CREATE LOOKUP TABLE ch9_json_ok (
    sensor_id VARCHAR(80) PRIMARY KEY,
    config    JSON,
    note      VARCHAR(80)
);

Design Criteria

SituationRecommended approach
Values frequently used in joins/searchesSeparate columns
Flexible attributes that differ by deviceJSON column
Numeric predicate queriesExtract into ordinary numeric columns
Primary keyStable identifier column
Frequent path queriesExtract into separate columns

Dedicated JSON path indexes are unsupported. For frequent predicates, first consider extracting the values into separate indexed columns.

CREATE LOOKUP TABLE ch9_json_fast (
    sensor_id VARCHAR(80) PRIMARY KEY,
    unit      VARCHAR(16),
    level     INTEGER,
    config    JSON
);

CREATE INDEX ch9_json_unit_idx ON ch9_json_fast(unit);

UPDATE and DELETE Predicates

UPDATE ch9_json
SET location = 'factory2'
WHERE config->'$.unit' = 'celsius';

DELETE FROM ch9_json
WHERE JSON_EXTRACT_INTEGER(config, '$.level') < 2;

Because the target scope can be broad, check the count with the same predicate before UPDATE/DELETE.

Clean up the example objects as follows. ch9_json_bad is excluded because its creation intentionally fails.

DROP TABLE ch9_json_fast;
DROP TABLE ch9_json_ok;
DROP TABLE ch9_json;

Considerations

  • LOOKUP supports JSON as an ordinary column.
  • JSON cannot be a primary key.
  • Dedicated JSON path indexes are unsupported.
  • Extract frequently searched values into ordinary LOOKUP columns.
  • Consider TRANSACTION or TAG tables if JSON path indexes are required.
Last updated on