sql一个查询,以为所选标识符选择最大/最小值(每个标识符的某种?)

时间:2019-03-24 12:44:22

标签: sql sqlite

我有简单的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'

1 个答案:

答案 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;