2015-12-11 2 views
0

Так у меня есть две таблицы, одна для ТВ-шоу, а другая для Эпизодов, схематически:SQLite запроса с двумя таблицами, чтобы найти «следующий эпизод смотреть»

show { 
    long id; 
    String title; 
} 

episode { 
int season; 
int episode; 
long showId (foreign key) 
int watched: Default (0) 
} 

Я пытаюсь выполнить запрос который вернется для каждого шоу, следующий эпизод пользователь должен посмотреть. Допустим, у меня есть два шоу: Show A и Show B, каждая строка - это сезон, а каждый номер - эпизод. Я представляю эпизоды с 0 (не смотрел) и 1 (смотрел).

A (2 seasons of 4 episodes) 
0000 
0000 

B (3 seasons of 3 episodes) 
000 
000 
000 

Для предыдущего примера, запрос должен возвращать:

A, season = 1, episode = 1 
B, season = 1, episode = 1 

Еще примеры:

A 
010 
000 
B 
111 
000 

Здесь запрос должен возвращать:

A, season = 1, episode = 3 
B, season = 2, episode = 1 

Другое:

A 
0100100101 
0001000000 
B 
1110000001 
0000000010 

Здесь запрос должен возвращать:

A, season = 2, episode = 5 
B, season = 2, episode = 10 

Как вы можете видеть, пользователь может пропустить эпизоды или смотреть их без того, но я всегда хочу, чтобы показать, как «рядом смотреть» тот, который сразу же рядом с самым дальним эпизодом.

Возможно ли это сделать в одном запросе? (может иметь подзапросы, конечно). Но я ищу один запрос здесь, поэтому я могу подключить его к Android Loader.

ответ

1

Отличная задача для аналитических функций. Однако, к сожалению, SQLite не имеет аналитических функций.

Первый шаг - найти последний увиденный эпизод за показ. Затем из всех эпизодов после этого выбирают список.

Эпизод состоит из двух частей; сезон и номер эпизода. Мы должны объединить их, чтобы их легко сравнить. Предположим, что для каждого хватит трех цифр, тогда мы могли бы сделать эпизод 5 второго сезона строки 002005, который лексически после любого 001xxx и до любого 003xxx и т. Д., А также после 002004 и до 002006. Идеальный ключ для получения эпизодов в порядке ,

Итак: 1. получите max (sortkey) за показ, 2. получите все эпизоды после этого, 3. получите min (sortkey) за показ из этих эпизодов, 4. получите записи с помощью этих sortkeys.

with series as 
(
    select 
    episode.*, 
    substr('000' || season, -3, 3) || substr('000' || episode, -3, 3) as sortkey 
    from episode 
) 
select 
    (select title from show where show.id = series.showid) as show_title, 
    series.season, 
    series.episode 
from series 
join 
(
    select showid, min(sortkey) as sortkey 
    from series 
    where sortkey > 
    (
    select coalesce(max(sortkey), '000000') 
    from series last_watched 
    where last_watched.watched = 1 
    and last_watched.showid = series.showid 
) 
    group by showid 
) next_episode on next_episode.showid = series.showid 
       and next_episode.sortkey = series.sortkey; 
+0

Здравствуйте, спасибо за ваш ответ. Ваше объяснение имеет смысл. Тем не менее, я пытался реализовать его (сам по себе, основываясь на ваших объяснениях и глядя на ваш код), но я еще не получил результата. Вот скрипка: http://sqlfiddle.com/#!9/27405/42. Не могли бы вы взглянуть на него? Я получаю шоу A, эпизод 2 сезона 2 и сериал 2 сезона 2. Так что для шоу B используется сезон/эпизод из шоу A:/ –

+0

И я думаю, что моя проблема в том, что в подзапросе, который принимает max (sortkey) всегда возвращает максимум всей таблицы (не для каждого шоу). –

+0

Ну, вы сделали скрипку с MySQL, которая сильно отличается от SQLite, но в любом случае ... Ваша проблема связана с использованием устаревшего синтаксиса соединения, который, как известно, подвержен ошибкам. Вместо этого используйте явные соединения! В вашем подзапросе вы получаете данные из шоу и эпизодов.Вы пересекаете эти таблицы, используя 'FROM show, episodes' вместо того, чтобы правильно их присоединять к' FROM показывает эпизоды JOIN ON ... '. Затем у вас есть 'show.id = episodes.showId' в вашем предложении WHERE. Но вам нужно * два * критерия на ShowId: ... –

Смежные вопросы