Можно ли выбрать несколько смещений с помощью SQL - PullRequest
0 голосов
/ 14 февраля 2020

Я бы хотел выбрать несколько смещений одним запросом SELECT SQL. Возможно ли это?

Например, допустим, у меня есть таблица непостоянных дат с именем dates.

date
----------
2020-01-01
2020-01-09
2020-01-16
2020-01-22
2020-01-29
2020-02-01
2020-02-04
2020-02-10
2020-02-13

. Я бы хотел выбрать 1-е, 4-е и 7-е смещения с самой последней даты. В этом примере запрос должен возвращать:

offset    date
------    -------
1         2020-02-10
4         2020-01-29
7         2020-01-09

В идеале я хотел бы написать запрос следующим образом:

SELECT
    *
FROM
    dates
ORDER BY
    date DESC
OFFSET
    (1, 4, 7)

Очевидно, что это не компилируется из-за LIMIT / Предложение OFFSET.

Я мог бы попробовать UNION, но он не только очень многословен, но и не работает, поскольку предложение LIMIT / OFFSET должно следовать после последнего UNION.

FAIL:

SELECT 1, date FROM dates ORDER BY date DESC LIMIT 1 OFFSET 1
UNION
SELECT 4, date FROM dates ORDER BY date DESC LIMIT 1 OFFSET 4
UNION
SELECT 7, date FROM dates ORDER BY date DESC LIMIT 1 OFFSET 7

Есть ли элегантный запрос для этого? Другой вариант, который я могу придумать, это использовать row_number () с оконной функцией, а затем сделать что-то вроде SELECT * WHERE row_number IN (1, 4, 7). ОДНАКО, в некоторых случаях я вынужден использовать более старую версию SQLite, которая не поддерживает оконные функции.

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Для более ранней версии SQLite вы можете использовать коррелированный запрос в предложении WHERE:

select t.date
from tablename t
where (select count(*) from tablename where date > t.date) in (1, 4, 7)

См. Демонстрационную версию . Результаты:

| date       |
| ---------- |
| 2020-01-09 |
| 2020-01-29 |
| 2020-02-10 |

Если вам также нужен столбец offset:

select
  (select count(*) from tablename where date > t.date) offset,
  t.date
from tablename t
where offset in (1, 4, 7)
order by offset 

См. Демоверсию . Результаты:

| offset | date       |
| ------ | ---------- |
| 1      | 2020-02-10 |
| 4      | 2020-01-29 |
| 7      | 2020-01-09 |
1 голос
/ 14 февраля 2020

Я думаю, что вы хотите row_number():

select t.*
from (select t.*,
             row_number() over (order by date desc) as offset
      from t
      where date < date('now')  -- you might want local time
     ) t
where offset in (1, 4, 7);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...