我有简单的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
组找到最小/最大:
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查询(实际上是SQL的sqlite子集)中编写呢?
如果我写:
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
中的SELECT
设置main_tbl
来进行整个JOIN查询。
更新
示例数据:
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'
答案 0 :(得分:2)
好吧,您可以使用以下命令将其写为一个查询:
SELECT m.id, m.start_time, MIN(s.data) as min_data, MAX(s.data) as max_data
FROM main_tbl m LEFT JOIN
second_tbl s
ON s.m_id = m.id
GROUP BY m.id
ORDER BY start_time DESC
LIMIT X OFFSET Y;
编辑:
您可以使用相关的子查询:
SELECT m.id, m.start_time,
(SELECT s.data FROM second_tbl s WHERE m.m_id = s.chosen_id AND SOME_CONDITION ORDER BY s.id ASC LIMIT 1) as min_data,
(SELECT s.data FROM second_tbl s WHERE m.m_id = s.chosen_id AND SOME_CONDITION ORDER BY s.id DESC LIMIT 1) as max_data
FROM main_tbl m
ORDER BY start_time DESC
LIMIT X OFFSET Y;