У меня три столбца в одной таблице Test
name, type, region
Значения выборки:
john IT ny john SALES ny john FINANCE ny lisa SALES ny lisa FINANCE ny
Из приведенного выше условия, как я могу отдать приоритет 1 ИТ, 2 – ПРОДАЖЕ и 3 – Финансам.
Я имею в виду, что для приведенных выше записей образца он должен содержать 2 записи
John IT ny Lisa SALES ny
Если записи сотрудников связаны с ИТ, а не только те, которые должны показывать, если не показывать СБЫТКИ, если нет, чем показывать «Финансы».
Я бы предложил добавить таблицу для хранения TYPES
и связанных с ними приоритетов – если вы добавите ограничение FOREIGN KEY
между таблицей и таблицей типов, вы можете утверждать, что тип всегда имеет приоритет.
Альтернативным способом получения приоритетов будет создание функции, которая принимает тип как входной сигнал и возвращает приоритет. Это даст аналогичную функциональность, как таблица, но немного более запутанной.
Кроме этого – я согласен с @Ben в том, что аналитические функции – лучший способ получить результаты.
SQL Fiddle
Настройка схемы Oracle 11g R2 :
CREATE TABLE types ( type VARCHAR2(20) PRIMARY KEY, priority NUMBER(3) ) / INSERT INTO types SELECT 'IT', 1 FROM DUAL UNION ALL SELECT 'SALES', 2 FROM DUAL UNION ALL SELECT 'FINANCE', 3 FROM DUAL UNION ALL SELECT 'MARKETING', NULL FROM DUAL / CREATE TABLE minions ( name VARCHAR2(30), type VARCHAR2(20), region VARCHAR2(2), FOREIGN KEY ( type ) REFERENCES types ( type ) ) / INSERT INTO minions SELECT 'john', 'IT', 'ny' FROM DUAL UNION ALL SELECT 'john', 'SALES', 'ny' FROM DUAL UNION ALL SELECT 'john', 'FINANCE', 'ny' FROM DUAL UNION ALL SELECT 'john', 'MARKETING', 'ny' FROM DUAL UNION ALL SELECT 'kevin', 'MARKETING', 'ny' FROM DUAL UNION ALL SELECT 'lisa', 'SALES', 'ny' FROM DUAL UNION ALL SELECT 'lisa', 'FINANCE', 'ny' FROM DUAL /
Запрос 1 :
SELECT name, MAX( m.type ) KEEP ( DENSE_RANK FIRST ORDER BY priority ) AS type, MAX( region ) KEEP ( DENSE_RANK FIRST ORDER BY priority ) AS region FROM minions m INNER JOIN types t ON ( m.type = t.type ) WHERE priority IS NOT NULL GROUP BY name ORDER BY name
Результаты :
| NAME | TYPE | REGION | |------|-------|--------| | john | IT | ny | | lisa | SALES | ny |
Вам нужно выбрать один, кажется, что предложение CASE было бы лучше:
select name , max(type) keep (dense_rank first order by priority asc) as type , max(region) keep (dense_rank first order by priority asc) as region from ( select a.* , case type when 'IT' then 1 when 'SALES' then 2 when 'FINANCE' then 3 end as priority from my_table a ) group by name
Функция FIRST
выбирает первое ранжированное значение, основанное на указанном порядке.