Как найти элементы в одном столбце для значений в других столбцах, имеющих в SQL не более 3 пробелов - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть представление sql, скажем emp_table, которое выглядит следующим образом:

+----------+----------+------+
| actor_id | movie_id | year |
+----------+----------+------+
|        2 |   280088 | 2002 |
|        2 |   396232 | 2000 |
|        3 |   376687 | 2000 |
|        4 |   336265 | 2001 |
|        5 |   135644 | 1953 |
|        6 |    12083 | 1996 |
|        7 |   252053 | 1993 |
|        7 |   402635 | 1992 |
|        7 |   409592 | 1995 |
|        8 |   101866 | 2000 |
|        9 |   336265 | 2001 |
|       10 |    12148 | 2000 |
|       11 |    80189 | 2001 |
|       12 |    12148 | 2000 |
|       13 |    80189 | 2001 |
|       14 |    70079 | 1982 |
|       15 |    12148 | 2000 |
|       16 |   242675 | 1991 |
|       17 |   105231 | 1993 |
|       17 |   242453 | 1988 |
+----------+----------+------+

... и так далее.Мне нужно найти всех actor_id, у которых никогда не было отставания в карьере более 3 лет.Это значит, что мне нужно рассчитать всех актеров, для которых, если я вычислю количество уникальных лет, в которых они снимались в фильме, а затем отсортирую их, то максимальная последовательная разница между годами никогда не будет превышать 3 года.Пожалуйста, помогите мне с этим SQL-запросом.Я пробовал sql self join, но не мог больше об этом думать.

Весь код SQL предназначен только для MySQL.

Примечание Вы можете считать, что есть толькоодна комбинация actor_id и movie_id.

Ожидаемый результат

+----------+----------+
| actor_id | max_gap  |
+----------+----------+
|        2 |   2      |
|        3 |   0      |
|        4 |   0      |
|        5 |   0      |
|        6 |   0      |
|        7 |   2      |
|        . |   .      |
|        . |   .      |
|        . |   .      |
|       17 |   5      |
+----------+----------+

И так далее

Примечание 2: Извините затак много изменений в выводе.Это окончательная версия, и после этого больше нет изменений.

Ответы [ 3 ]

0 голосов
/ 05 февраля 2019

С MySQL 8 и MariaDB 10.2 вы можете использовать оконную функцию LEAD(), чтобы получить следующий год подряд игры дляактер (или LAG() для последнего).Тогда вам просто нужно получить максимальную разницу во внешнем запросе.

with tmp as (
  select 
      actor_id,
      year,
      lead(year) over (partition by actor_id order by year) as year_lead
  from emp_table e
)
select actor_id, coalesce(max(year_lead - year), 0) as max_gap
from tmp
group by actor_id
having max_gap <= 3;

Демо: https://www.db -fiddle.com / f / cWChT2TqLuRT8bW1zcM9G2 / 0

0 голосов
/ 05 февраля 2019

Самостоятельное объединение таблицы и группы с помощью actor_id:

select
  e1.actor_id, max(coalesce(e2.year, e1.year) - e1.year) max_gap
from emp_table e1 left join emp_table e2
on 
  e2.actor_id = e1.actor_id
  and 
  e2.year = (
    select min(year) from emp_table where actor_id = e1.actor_id and year > e1.year
  )
group by e1.actor_id  
having max_gap <= 3

См. demo

0 голосов
/ 05 февраля 2019

Я изначально начал с подхода против объединения, но затем изменил его, увидев ваше требование по максимальному разрыву.

Подход, приведенный ниже, начинается с подзапроса, который сам использует коррелированный подзапрос для вычисления прогнозного взгляда.годовой разрыв, для каждой записи актера и года.Затем он агрегирует по субъекту и утверждает, что промежуток, превышающий 3 года, никогда не возникает.

SELECT actor_id, MAX(gap) AS max_gap
FROM
(
    SELECT
        e1.actor_id,
        ABS(e1.year - COALESCE((SELECT e2.year FROM emp_table e2
                       WHERE e2.actor_id = e1.actor_id AND e2.year > e1.year
                       ORDER BY e2.year LIMIT 1), e1.year)) AS gap
    FROM emp_table e1
) t
GROUP BY
    actor_id
HAVING
    MAX(gap) <= 3;

Обратите внимание, что вызов COALESCE очень необходим из-за крайнего случая самого последнего года действия актера.В этом случае нет перспективного года, но мы хотим сделать скидку в этом году.

...