2013-07-14 2 views
1

Я пытаюсь создать отчет на основе приведенных ниже двух таблицах:Генерация «распределения ресурсов» отчетов с помощью SQL

Name  Start Year End Year No. Of Students Fill Order 
School-ABC  2000   2004   1    1 
School-DEF  2000   2004   2    3  
School-GHI  2000   2004   1    2  

    Name  Start Year End Year Joined On 
Student-1  2000   2004  01-Jan 
Student-2  2000   2004  03-Jan 
Student-3  2000   2004  02-Jan 
Student-4  2000   2004  15-Jan 

Ожидаемый выход ниже:

Name  Start Year End Year Joined On School 
Student-1  2000   2004  01-Jan  School-ABC 
Student-2  2000   2004  03-Jan  School-DEF 
Student-3  2000   2004  02-Jan  School-GHI 
Student-4  2000   2004  15-Jan  School-DEF  

логика формирования данных :

  1. Первая таблица содержит список школ и мест, доступных (наряду с приоритетом, в котором места будут быть выделены студентам на основе FCFS)
  2. Вторая таблица содержит данные о списке учащихся, обучающихся в школах, с датой их поступления и началом/окончанием курса курса.
  3. Я должен заполнить, основываясь на «Заполняющем заказе», школе, которая выделяется каждому ученику.

Проанализировав проблему на некоторое время, я пришел к выводу, что это может быть невозможно достичь, используя только отдельные запросы. В настоящее время я планирую сделать это, используя два курсора для каждой таблицы и обработать записи по строкам. Есть ли лучший способ сделать это или это возможно с помощью выборочных утверждений? ТИА

Примечание:

  • базы данных я использую Oracle 10g
  • Я не могу создавать временные таблицы или изменить данные в любой из таблиц. Я строго имею доступ только для чтения к базе данных.
+0

В вашем входе, студент 3 вступил в январе 15-го. В своем выступлении он присоединился 2 января. – Andomar

+0

Спасибо за исправление. Это была опечатка. –

ответ

1

Вы можете использовать аналитические функции Oracle. row_number() over() может назначать номер каждому учащемуся на основе даты их присоединения. sum() over() может рассчитать первого и последнего учеников для каждой школы. Объединяя два вы получите:

select stud.name 
,  stud.startyear 
,  stud.endyear 
,  stud.joinedon 
,  schl.name as SchoolName 
from (
     select name 
     ,  coalesce(sum(NoOfStudents) over (order by FillOrder 
        range between unbounded preceding and 1 preceding),0)+1 FirstStudent 
     ,  sum(NoOfStudents) over (order by FillOrder) as LastStudent 
     from Schools 
     ) schl 
join (
     select row_number() over (order by JoinedOn) as StudentRank 
     ,  Students.* 
     from Students 
     ) stud 
on  stud.StudentRank between schl.FirstStudent and schl.LastStudent 
order by 
     stud.name 

Live example at SQL Fiddle.

+0

Спасибо за быстрый ответ. Раньше я никогда не использовал аналитические функции, и пока я не увидел, что ваш ответ, о котором я думал, может быть тем, чего я хотел, не был возможен с помощью простых операторов выбора. 'На самом деле, входные данные и ожидаемый результат были немного разными (как-то я пропустил, чтобы включить их в исходный вопрос, когда я изначально разместил). Я создал скрипт SQL и решил его. Я делаю это правильно или есть лучший способ сделать это? [SQL Fiddle] (http://sqlfiddle.com/#!4/305c6/42) Меня больше беспокоит производительность моего решения, когда набор данных огромен! –

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