2014-11-12 2 views
3

У меня есть запрос, который я думаю, должно быть что-то вроде этого (декодирование будет гораздо больше)SQL Decode - ВЫБРАТЬ & WHERE

SELECT 
firstName, 
lastName, 
decode(mathMrk, 80, 'A', mathMrk) as decodeMath, 
decode(engMrk, 80, 'A', engMrk) as decodeEng, 
FROM table 
WHERE 
decode(mathMrk, 80, 'A', mathMrk) IN ('A','B','C') 
OR decode(engMrk, 80, 'A', engMrk) IN ('A','B'); 

ИЛИ где может быть?

WHERE 
decodeMath IN ('A','B','C') 
OR decodeEng IN ('A','B'); 

Цель состоит в том, чтобы получить все из студенческих отметок в определенном формате, но если сказать, пользователь хочет видеть студентов только «А» в английском или «A» в математике (на выбор и причина того, где), они видят только тех студентов, но все связанные метки

В основном вопрос: если я декодирую и псевдоним в SELECT, мне также нужно декодировать в ГДЕ? Было бы лучше, если бы я преобразовал пользовательские настройки в соответствие с db вместо того, чтобы пытаться декодировать? Хотя мой db имеет два разных типа данных в качестве меток, я пытаюсь преобразовать в один и тот же тип, который также выбирает пользователь.

+0

Oracle, предположительно? –

+0

есть, оракул .. ответ ограничение – Emma

ответ

1

Вы не можете использовать имена псевдонимов из списка выбора в предложении where, только в пункте order by. Причина этого заключается в том, что SQL обрабатывается пошагово. Сначала вычисляются соответствующие строки (предложение where), затем вычисляются выбранные поля (предложение SELECT) и последние строки сортируются (пункт order by).

Существует несколько способов решения проблемы. Наиболее распространенным способом является использование представления (явно или неявно):

SELECT 
firstName, 
lastName, 
decodeMath, 
decodeEng, 
FROM 
    (SELECT 
    firstName, 
    lastName, 
    decode(mathMrk, 80, 'A', mathMrk) as decodeMath, 
    decode(engMrk, 80, 'A', engMrk) as decodeEng, 
    FROM table) tableview 
WHERE 
decodeMath IN ('A','B','C') 
OR decodeEng IN ('A','B'); 

Вы можете иметь весь код для представления в ваше отборного (как в приведенном выше примере), или вы можете создать представление отдельно, а затем использовать его, как будто это была таблица. Последнее очень удобно, если вам нужно одно представление в нескольких SQL.

Я также рекомендую вам создать функцию для перевода с mrk на класс.

CREATE OR REPLACE FUNCTION decodeMrk(mrk in Integer) RETURN Varchar2(1) IS 
BEGIN 
    return CASE WHEN mrk >= 80 THEN 'A' 
       WHEN mrk >= 60 THEN 'B' ... -- and so on 
     END; 
END; 

Затем вы можете использовать его в виде:

decodeMrk(mathMrk) as decodeMath, 
2

Включите его в предложение CASE. Вы также можете использовать CASE в предложении WHERE.

Это (простой) рабочий пример, который должен запускаться на любой схеме Oracle.
Я преобразую object_id в класс от 1 до 100 для этого примера.

with grades as 
     (select object_name as student, 
       mod (object_id, 99) + 1 as mathmark, 
       case 
        when mod (object_id, 100) + 1 between 0 and 20 then 'F' 
        when mod (object_id, 100) + 1 between 21 and 40 then 'D' 
        when mod (object_id, 100) + 1 between 41 and 60 then 'C' 
        when mod (object_id, 100) + 1 between 61 and 80 then 'B' 
        when mod (object_id, 100) + 1 between 81 and 100 then 'A' 
       end 
        as mathdecode 
      from user_objects) 
select * 
    from grades 
where mathdecode in ('A', 'B')