#sql
Вопрос:
У меня есть стол results
, который выглядит так:
ID | Оценка | день |
---|---|---|
1 | 5 | ‘2001-01-01’ |
1 | 10 | ‘2001-02-01’ |
1 | 8 | ‘2001-03-01’ |
2 | 3 | ‘2001-01-01’ |
2 | 10 | ‘2001-02-01’ |
3 | 2 | ‘2001-01-01’ |
3 | 5 | ‘2001-02-01’ |
3 | 3 | ‘2001-03-01’ |
4 | 8 | ‘2001-01-01’ |
5 | 10 | ‘2001-01-01’ |
Я хотел бы выбрать все строки, где rating = 10
это достигнуто, до или когда это будет достигнуто, чтобы получить что-то вроде этого:
ID | Оценка | день |
---|---|---|
1 | 5 | ‘2001-01-01’ |
1 | 10 | ‘2001-02-01’ |
2 | 3 | ‘2001-01-01’ |
2 | 10 | ‘2001-02-01’ |
5 | 10 | ‘2001-01-01’ |
Каков SQL-запрос для этого?
Комментарии:
1. Я удалил конфликтующие теги СУБД. Пожалуйста, добавьте только один тег для продукта базы данных, который вы действительно используете.
Ответ №1:
Один метод использует коррелированный подзапрос:
select t.*
from t
where t.day <= (select min(t2.day)
from t t2
where t2.id = t.id and t2.rating = 10
);
Другой метод использует функцию окна:
select t.*
from (select t.*,
min(case when rating = 10 then day end) over (partition by id) as day_10
from t
) t
where day <= day_10;
Ответ №2:
SELECT *
FROM table t1
WHERE NOT EXISTS ( SELECT NULL
FROM table t2
WHERE t1.id = t2.id
AND t1.day > t2.day
AND t2.rating = 10 )
AND EXISTS ( SELECT NULL
FROM table t3
WHERE t1.id = t3.id
AND t3.rating = 10 );
WITH
cte AS ( SELECT *, SUM(rating = 10) OVER (PARTITION BY id ORDER BY day DESC) ok
FROM table )
SELECT *
FROM table
WHERE ok;