Почему этот SQL-запрос выполняется вечно? - PullRequest
0 голосов
/ 22 мая 2019

Я пытаюсь найти «Найти актеров, которые никогда не были безработными более 3 лет подряд».

Схема таблицы выглядит следующим образом

--------------------   -----------------------   ----------------------
|   Movie          |   |     Person           |  |       Cast         |
--------------------   ------------------------  ----------------------
| MovieID  | year  |   |  PersonID  | Gender  |  | MovieID | PersonID |
--------------------   ------------------------  ----------------------

Я пытался присоединиться иделать подзапросы.Однако мой SQL-оператор работает всегда на sqlite

SELECT DISTINCT TRIM(A.PID), A.NAME FROM PERSON A 
WHERE TRIM(A.PID) NOT IN (

SELECT DISTINCT TRIM(B.PID) FROM M_CAST B, MOVIE C WHERE TRIM(B.MID) = 
TRIM(C.MID) AND EXISTS (

SELECT TRIM(D.MID) FROM M_CAST D, MOVIE E WHERE TRIM(D.MID) = TRIM(E.MID) 
AND TRIM(B.PID) = TRIM(D.PID) AND (CAST (SUBSTR(TRIM(E.YEAR), 
LENGTH(TRIM(E.YEAR)) -3 , 4) AS INT) - 3) >

CAST (SUBSTR(TRIM(C.YEAR), LENGTH(TRIM(C.YEAR)) -3 , 4) AS INT) AND NOT 
EXISTS (

SELECT TRIM(F.MID) FROM M_CAST F, MOVIE G WHERE TRIM(F.MID) = (G.MID) AND 
TRIM(B.PID) = TRIM(F.PID) AND 
CAST (SUBSTR(TRIM(C.YEAR), LENGTH(TRIM(C.YEAR)) -3 , 4) AS INT) < CAST 
(SUBSTR(TRIM(G.YEAR), LENGTH(TRIM(G.YEAR)) -3 , 4) AS INT) AND
CAST (SUBSTR(TRIM(G.YEAR), LENGTH(TRIM(G.YEAR)) -3 , 4) AS INT) < CAST 
(SUBSTR(TRIM(E.YEAR), LENGTH(TRIM(E.YEAR)) -3 , 4) AS INT)
)

)

)




CAST (SUBSTR(TRIM(C.YEAR), LENGTH(TRIM(C.YEAR)) -3 , 4) AS INT) #was used 
since the year had some special characters and was used to extract only the 
last 4 digits (year)

Ожидаемый результат - отобразить все имена участников, которые не были безработными в течение более 3 лет, но мой запрос выполняется вечно, но безрезультатно.

1 Ответ

0 голосов
/ 22 мая 2019

Это сложный вопрос. Гораздо проще использовать оконные функции в самых последних версиях SQLite.

Вот один из подходов:

  • Получите четкий список всех лет работы человека.
  • Используйте этот список, чтобы найти людей, которые работали три года подряд (то есть данный год плюс следующие два).
  • Выберите всех, кого нет в этом списке.

Вы можете остановиться здесь и поработать над проблемой самостоятельно. Как редакционный комментарий, это было бы намного проще с оконными функциями. Но только самые последние версии SQLite поддерживают их.

Спойлер:

with py as (
      select distinct c.personid, m.year
      from cast c join
           movie m
           on c.movieid = m.movieid
     ),
     py3 as (
      select distinct py.personid
      from py join
           py py1
           on py1.personid = py.personid and
              py1.year = py.year + 1 join
           py py2
           on py2.personid = py.personid and
              py2.year = py.year + 2
     )
select p.*
from person p
where not exists (select 1
                  from py3
                  where py3.personid = p.personid
                 );

Здесь - это скрипта db <>, иллюстрирующая, что код работает. (Нет данных, просто демонстрация правильности кода.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...