Результат запроса порядка oracle в последовательности из предложений OR - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть таблица oracle со структурой, похожей на:

School {
 Student_Id,
 Student_Name,
 Class,
 Sport,
 Club
}

Я хочу написать запрос, чтобы выбрать всех студентов, которые принадлежат к X классу или Y Sport , или Z club .

Но я хочу упорядочить результат на основе последовательности моих условий OR.

То есть все учащиеся, принадлежащие к X классу придут первыми, прежде чем студенты Y спорта. Затем приедут студенты клуба Z.

Также, нет повторяющихся результатов. То есть, если Джон из класса X и также принадлежит спорту Y, то он должен появиться только один раз и быть на вершине всех результатов спорта Y.

Ответы [ 3 ]

1 голос
/ 28 апреля 2020

Вот как я понял вопрос:

SQL> with school (student_name, class, sport, club) as
  2    (select 'Scott', 'x', 'a', 'c' from dual union all
  3     select 'Mike' , 'b', 'c', 'z' from dual union all
  4     select 'Kate' , 'x', 'y', 'z' from dual union all
  5     select 'John' , 'x', 'b', 'd' from dual union all
  6     select 'Vito' , 'd', 'e', 'g' from dual
  7    )
  8  select * from school
  9  where class = 'x' or sport = 'y' or club = 'z'
 10  order by case when class = 'x' then 1 end,
 11           case when sport = 'y' then 2 end,
 12           case when club  = 'z' then 3 end;

STUDENT CLASS SPORT CLUB
------- ----- ----- -----
Kate    x     y     z
Scott   x     a     c
John    x     b     d
Mike    b     c     z

SQL>

Если это не так, пожалуйста, опубликуйте пример данных и ожидаемый результат.

0 голосов
/ 28 апреля 2020

Я бы написал это как:

select s.*
from school s
where class = 'X' or sport = 'Y' or club = 'Z'
order by (case when class = 'X' then 1
               when sport = 'Y' then 2
               when club = 'Z' then 3
          end)

Если вы не хотите повторять условия, вы можете использовать подзапрос, CTE или - в Oracle 12 C - боковое соединение:

select s.*
from school s cross join lateral
     (select (case when class = 'X' then 1
                   when sport = 'Y' then 2
                   when club = 'Z' then 3
              end) as ord
      from dual
     ) x
where x.ord is not null
order by x.ord
0 голосов
/ 28 апреля 2020
select student_id
, case when class='X' then 1
       when sport = 'Y' then 2 
       when club='Z' then 3
       else 4
  end as Ordr
from School 
WHERE class='X' or sport = 'Y' or club='Z'
Order by ordr

Объяснение:

WHERE class='X' or sport = 'Y' or club='Z' просто реализует желаемую фильтрацию.

Пользовательский порядок реализуется путем создания дополнительного столбца с именем ordr и использовать его в предложении ORDER BY. Этот столбец создается с помощью оператора case. Порядок написания этого важен, потому что выражение CASE оценивается как первое истинное условие, а если нет истинного условия, оно оценивается как часть ELSE.

Таким образом, все учащиеся, принимающие класс X, получат Ордр 1, независимо от вида спорта и клуба.

Если учащийся не посещает урок X, выражение попытается оценить, будет ли ученик заниматься спортом Y, и если это так, этот студент получит присваивает ордеру 2 независимо от других значений столбца.

Тогда, если учащийся не принимает ни класс X, ни вид спорта Y, выражение случая проверит, находится ли студент в клубе Z. Если это правда, он будет присвоил ордеру 3.

Наконец, если ученик не находится ни в классе X, не занимается спортом Y или в клубе Z, ему будет присвоено ордра 4.

ORDER BY is ASCENDING по значению degfault, значение 1 будет отображаться до 2 и т. д.

То, что этот алгоритм не делает, что вы можете сказать из приведенного выше объяснения, - это расставить приоритеты для ученика. на занятии класса X, спорт Y, клуб Z над кем-то, кто берет только класс X.

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