SQLite: использовать результат подзапроса в другом подзапросе - PullRequest
0 голосов
/ 25 октября 2019

У меня есть следующая таблица с данными

id | COL1
=========
1  |  b 
2  |  z 
3  |  b 
4  |  c 
5  |  b 
6  |  a 
7  |  b 
8  |  c 
9  |  a 

Итак, я знаю идентификатор «z» (ID = 2) в таблице, и я назову его Z_ID. Мне нужно получить строки между «а» и «с» (в том числе «а» и «с»). Это должно быть первое «a» после Z_ID. 'c' должно идти после Z_ID и после 'a', которое я нашел ранее.

Результат, который я ищу:

id | COL1
=========
6  |  a 
7  |  b 
8  |  c 

Мой SELECT выглядит следующим образом

SELECT * FROM table WHERE id >= ( SELECT MIN(ID) FROM table WHERE COL1 = 'a' AND ID > 2 ) AND id <= ( SELECT MIN(ID) FROM table WHERE COL1 = 'c'AND ID > 2 and ID > ( SELECT MIN(ID) FROM table WHERE COL1 = 'a' AND ID > 2 ) )

Я получаю желаемый результат. Но я беспокоюсь о производительности, потому что я использую один и тот же подзапрос два раза. Есть ли способ повторно использовать результат из первого подзапроса? Может быть, есть более чистый способ получить нужный мне результат?

Ответы [ 2 ]

1 голос
/ 25 октября 2019

Для этого вы можете использовать оконные функции:

select t.*
from (select t.*,
             min(case when id > min_a_id and col1 = 'c' then id end) over () as min_c_id
      from (select t.*,
                   min(case when col1 = 'a' then id end) over () as min_a_id
            from (select t.*,
                         min(case when col1 = 'z' then id end) over () as z_id
                  from t
                 ) t
            where id > z_id
           ) t
     ) t
where id >= min_a_id and id < min_c_id;
1 голос
/ 25 октября 2019

Используйте CTE, который будет возвращать только один раз результат подзапроса, который вы используете дважды:

WITH cte AS (
  SELECT MIN(ID) minid
  FROM tablename
  WHERE COL1 = 'a' AND ID > 2  
)  
SELECT t.*
FROM tablename t CROSS JOIN cte c
WHERE t.id >= c.minid
AND t.id <= (
  SELECT MIN(ID)
  FROM tablename
  WHERE COL1 = 'c' and ID > c.minid
)

В предложении WHERE вашего второго запроса:

WHERE COL1 = 'c'AND ID > 2 and ID > (...

условие AND ID > 2 не нужно, потому что следующее условие and ID > (... гарантирует, что ID будет больше, чем 2, поэтому я не использую его в своем коде. Смотрите демо . Результаты:

| id  | COL1 |
| --- | ---- |
| 6   | a    |
| 7   | b    |
| 8   | c    |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...