2015-11-03 4 views
0

Название может не иметь смысла, поэтому я предоставлю некоторый контекст.SQL - Получите минимально минимальные числа

У меня есть стол, назовите его Кино.

Фильм кортеж имеет значения: Имя, директор, жанр,

Год

Я пытаюсь создать запрос, который позволяет мне вернуть все директора, которые никогда не выпустили два последовательных фильмов ужасов с более чем 4-х лет Кроме.

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

Моя попытка была:

SELECT D1.Director 
FROM Movies D1 
WHERE D1.Director NOT IN 
(SELECT D2.Director FROM Director D2 
WHERE D2.Director = D1.Director 
AND D2.Genre = 'Horror' 
AND D1.Genre = 'Horror' AND D2.Year - D1.Year > 4 
OR D1.Year - D2.Year > 4) 

, который не работает по очевидным причинам.

У меня также было несколько попыток с помощью объединений, и оно работает над фильмами, которые следуют примеру 2000, 2003, 2006, но не удается, если более 3-х фильмов.

ответ

0

Вы можете попробовать это:

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

WITH TempTable AS (
    SELECT 
    Name, 
    Director, 
    Genre, 
    Year, 
    LAG(Year) OVER (PARTITION BY Name, Director, Genre ORDER BY Year ASC) AS 'PriorYear' 
    FROM 
    Movies 
    WHERE 
    Genre = 'Horror' 
) 

SELECT 
    Name, 
    Director 
FROM 
    TempTable 
GROUP BY 
    Name, 
    Director 
HAVING 
    MAX(Year-PriorYear) < 2 
+0

Спасибо за ответ. Как работают LAG и PARTITION - я никогда не использовал эти 2 функции. – user3186023

+0

LAG - это то, что называется оконной функцией, оно работает подобно RANK и ROW_NUMBER. LAG вернет предыдущую запись (в соответствии с компонентом ORDER BY), LEAD вернет следующую запись, RANK вернет ранжирование с помощью связей {(1,1,2,3) => (1,1,3,4) } ROW_NUMBER вернет номер строки {(1,1,2,2) => (1,2,3,4)}. В принципе, PARTITION будет работать подобно команде group by, что означает, что ранг будет сброшен с каждой другой комбинацией. Это означает, что LAG вернет предыдущий год для этого имени/режиссера/жанра и вернет NULL, когда нет предыдущей записи. – hcaelxxam

+0

Вы также можете проверить https://msdn.microsoft.com/en-us/library/hh231256.aspx. – hcaelxxam

0

Попробуйте это:

SELECT * FROM (
    SELECT director, min(diff) as diff FROM (
     SELECT m1.director, m1.year as year1, m2.year as year2, m2.year-m1.year as diff 
     FROM `movies` m1, movies m2 
     WHERE m1.director = m2.director and m1.name <> m2.name and m1.year<=m2.year 
     and m1.genre='horror' and m2.genre='horror' 
    ) d1 group by director 
) d2 WHERE diff>4 

Во-первых, во внутреннем Выберите это будет список всех пар кино фильмов ужасов режиссеров с разницей в год рассчитывается, то минимальное из них выбраны (для consecutiveness), то более 4 лет выбираются отличия ...

+0

Если есть 3 фильма 2000, 2003 и 2006. Тогда «FROM m1, m2» создаст (2000, 2003), (2000, 2006), (2003, 2006). Затем «m1.year-m2.year» вернется 3, 6 и 3. Это будет означать, что режиссер действительно делал фильмы более чем на 4 года друг от друга, учитывая 6, но эти 2 не последовательны. – hcaelxxam

+0

@hcaelxxam это как раз проблема, с которой я столкнулся с моим кодом, но вы просто сформулировали это лучше. – user3186023

+0

, поэтому минимальный diff выбран для сравнения с 4! – vacsora