У меня есть простая структура sql:
CREATE TABLE main_tbl(
id INTEGER PRIMARY KEY ASC,
start_time TEXT NOT NULL,
);
CREATE TABLE second_tbl (
id INTEGER PRIMARY KEY AUTOINCREMENT,
data BLOB,
m_id INTEGER NOT NULL,
FOREIGN KEY(m_id) REFERENCES main_tbl(id) ON DELETE CASCADE
);
CREATE INDEX m_id_idx ON second_tbl (m_id);
CREATE INDEX start_time_idx ON main_tbl (start_time);
И я хочу найти некоторые элементы из main_tbl
:
SELECT id,start_time FROM main_tbl ORDER BY start_time DESC LIMIT X OFFSET Y;
, а затем для выбранного набораmain_tbl.id
find min / max:
SELECT data FROM second_tbl WHERE m_id=chosen_id AND SOME_CONDITION ORDER BY second_tbl.id ASC LIMIT 1
UNION
SELECT data FROM second_tbl WHERE m_id=chosen_id AND SOME_CONDITION ORDER BY second_tbl.id DESC LIMIT 1
На псевдоязыке это выглядит так:
foreach chosen_id IN (SELECT id,start_time FROM main_tbl ORDER BY start_time DESC LIMIT X OFFSET Y)
SELECT data FROM second_tbl WHERE m_id=chosen_id AND SOME_CONDITION ORDER BY second_tbl.id ASC LIMIT 1
UNION
SELECT data FROM second_tbl WHERE m_id=chosen_id AND SOME_CONDITION ORDER BY second_tbl.id DESC LIMIT 1
Но как записать это в одном запросе SQL (на самом деле sqlite подмножество SQL)?
Если я напишу:
WITH chosen_ids(id,data) AS (SELECT id,start_time FROM main_tbl ORDER BY start_time DESC LIMIT X OFFSET Y)
SELECT data FROM second_tbl WHERE m_id IN (SELECT id from chosen_ids) AND SOME_CONDITION ORDER BY second_tbl.id ASC LIMIT 1
, тогда я получу мининим для всех chosen_ids
, а мне нужно для каждого из них.
Если я вместо этого использую JOIN
из WITH
Я могу установить только LIMIT/OFFSET
для всего запроса JOIN, а не только для SELECT
из main_tbl
.
Обновление
Пример данных:
sqlite> SELECT id,start_time FROM main_tbl ORDER BY start_time DESC LIMIT 5 OFFSET 100;
900|2019-03-14T08:36:26.324937205+00:00
899|2019-03-14T06:36:26.324937205+00:00
898|2019-03-14T04:36:26.324937205+00:00
897|2019-03-14T02:36:26.324937205+00:00
896|2019-03-14T00:36:26.324937205+00:00
тогда я запустил подзапросы для 896-900, вот пример для 900:
sqlite> SELECT quote(data) FROM second_tbl WHERE m_id=900 AND data IS NOT NULL ORDER BY second_tbl.id ASC LIMIT 1;
X'000000008A128A5C00000000F5255E13000000000000F03F0000000000000040000000000000084000000000000010400000000000001440010000000000001840'
sqlite> SELECT quote(data) FROM second_tbl WHERE m_id=900 AND data IS NOT NULL ORDER BY second_tbl.id DESC LIMIT 1;
X'00000000AA2E8A5C00000000F544680D000000000000F03F0000000000000040000000000000084000000000000010400000000000001440010000000000001840'