SQLite: LIMIT значения в зависимости от условия - PullRequest
1 голос
/ 09 мая 2019

С учетом следующей таблицы:

ID   A    B
-----------
1    6    5
2    3    2
3    5    1
4    5    5
5    9    8
6    1    7

Мне нужно SELECT первые X строк, которые удовлетворяют условию (A - B)> 0 Так что это не может быть:

SELECT ID FROM TABLE WHERE (A - B) > 0

В противном случае я получу строку с идентификатором 5, а я бы остановился на строке 3.

Можно ли записать условие в операторе LIMIT? Некоторые как:

SELECT ID FROM TABLE LIMIT (A - B) > 0

Как я могу это сделать? Есть ли альтернативы?

Примечание: когда я пишу "первые X строк", я имею в виду возрастающий порядок по ID.

UPDATE: Я не правильно объяснил, извините. Я не знаю значения X. Я сказал X как неизвестную переменную, в зависимости от таблицы. Я перефразирую требование:

Мне нужно выбрать все строки (начиная с ID 1) до условия (A - Б)> 0 не выполнено.

Ответы [ 4 ]

1 голос
/ 09 мая 2019

Вы должны быть осторожны, если нет строк, соответствующих конечному условию.

Вот метод, который всегда работает:

SELECT t.ID
FROM test t CROSS JOIN
     (SELECT MIN(id) as min_id
      FROM test
      WHERE A <= B
     ) tt
WHERE t.id < tt.min_id OR tt.min_id IS NULL;

Здесь - это дБ <> скрипка. (Это происходит с использованием MySQL; это потому, что создание таблицы в SQLite не работает.)

1 голос
/ 09 мая 2019

Вы можете попробовать это:

SELECT ID FROM TABLE WHERE ID < (SELECT MIN(ID) FROM TABLE WHERE (A - B) <= 0) ORDER BY ID
0 голосов
/ 09 мая 2019

Это звучит как основная проблема пропусков и островов, когда вы хотите найти только первый остров. Подобные вещи легко решить с помощью оконных функций, добавленных в sqlite 3.25 (и поэтому этот ответ не будет работать с более старыми версиями).

Учитывая эту таблицу:

CREATE TABLE test(id INTEGER PRIMARY KEY, a INTEGER, b INTEGER);
INSERT INTO test VALUES(1,6,5);
INSERT INTO test VALUES(2,3,2);
INSERT INTO test VALUES(3,5,1);
INSERT INTO test VALUES(4,5,5);
INSERT INTO test VALUES(5,9,8);
INSERT INTO test VALUES(6,1,7);

этот запрос:

WITH islands AS
  (SELECT id, a, b
        , row_number() OVER (PARTITION BY a - b > 0 ORDER BY id) AS isle_rn
   FROM test)
SELECT id, a, b
FROM islands
WHERE id = isle_rn AND a - b > 0
ORDER BY id;

производит

id          a           b         
----------  ----------  ----------
1           6           5         
2           3           2         
3           5           1         

По сути, он разбивает таблицу на два раздела: те, где a - b > 0 - это истина, и те, где она - ложь. Каждый раздел сортируется по id, и каждая строка затем нумеруется. Наконец, возвращаются только те строки, в которых это число равно id - первая строка, где условие ложно, приведет к тому, что все последующие строки, для которых верно, имеют разные id и номер строки. Дополнительная проверка, что a - b > 0 существует, чтобы поймать случай, когда id 1 является ложным, и никакие строки, таким образом, не должны быть возвращены.

Предполагается, что id всегда начинается с 1 и не имеет пробелов. Если это не так, этот вариант добавляет порядковый номер строки, который используется вместо id:

WITH islands AS
  (SELECT id, a, b
        , row_number() OVER (ORDER BY id) AS rn
        , row_number() OVER (PARTITION BY a - b > 0 ORDER BY id) AS isle_rn
   FROM test)
SELECT id, a, b
FROM islands
WHERE isle_rn = rn AND a - b > 0
ORDER BY id;
0 голосов
/ 09 мая 2019

Вы были очень близки. Вот SQL Fiddle

SELECT * FROM Table WHERE (A - B) > 0 LIMIT 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...