2015-11-24 2 views
0

У меня есть структура таблицы (которую я не проектировал и не могу изменить), которая использует поле varchar для хранения атрибута об объекте. Я хотел бы написать SQL-запрос для поиска двух атрибутов в частности и объединить несколько строк результата в отдельные строки. Чтобы проиллюстрировать это, мои таблицы похожи на это:Группа Oracle по запросу SQL путем сопоставления поля varchar

company 
============= 
| id | name | 
------------- 
| 1 | co1 | 
| 2 | co2 | 
| 3 | co3 | 
============= 

agent 
==================================== 
| id | name | company_id | type | 
------------------------------------ 
| 1 | Tom |   1 | 'type1' | 
| 2 | Bob |   1 | 'type2' | 
| 3 | Bill |   2 | 'type1' | 
| 4 | Jack |   2 | 'type2' | 
| 5 | John |   3 | 'type1' | 
| 6 | Joe |   3 | 'type2' | 
==================================== 

type1 и type2 жестко закодировано в программное обеспечение в качестве допустимых значений (опять-таки, я не писал), поэтому поиск этих значения должен быть успешным (null разрешено). Итак, я должен основывать свой поиск на этих значениях.

Как новичок, я мог бы написать этот SQL:

select c.name, a.name, a.type 
from company c 
inner join agent a on c.id = a.company_id 

и перебирать эти результаты в моих программах (программа Java):

=========================== 
| c.name | a.name | type | 
--------------------------- 
| co1 | Tom | type1 | 
| co1 | Bob | type2 | 
| co2 | Bill | type1 | 
| co2 | Jack | type2 | 
| co3 | John | type1 | 
| co3 | Joe | type2 | 
=========================== 

Но я надеялся, что буду способ сочетать ряды с чем-то более эффективным:

-- my failed attempt at writing this query 
select c.name, a.name as type_1_agent, a.name as type_2_agent 
from company c 
inner join agent a on c.id = a.company_id 
group by c.id -- ? 
where -- ? 

results: 

====================================== 
| name | type_1_agent | type_2_agent | 
-------------------------------------- 
| co1 |   Tom |   Bob | 
| co2 |   Bill |   Jack | 
| co3 |   John |   Joe | 
====================================== 

Возможно ли это?

ответ

0

Вы можете сделать это с функциональностью PIVOT, например, так:

select company,type_1_agent,type_2_agent 
from 
(select a.name as agentname, a.type as agenttype,c.name as company 
from agent a 
inner join company c on c.id = a.company_id 
) s 
pivot 
(max(agentname) for agenttype in ('type1' type_1_agent,'type2' type_2_agent)) p 
order by company 

Demo

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

0

Oracle:

WITH company (id, name) AS (
    SELECT 1, 'co1' FROM DUAL UNION ALL 
    SELECT 2, 'co2' FROM DUAL UNION ALL 
    SELECT 3, 'co3' FROM DUAL 
), 
agent (id, name, company_id, type) AS (
    SELECT 1, 'Tom', 1, 'type1' FROM DUAL UNION ALL 
    SELECT 2, 'Bob', 1, 'type2' FROM DUAL UNION ALL 
    SELECT 3, 'Bill', 2, 'type1' FROM DUAL UNION ALL 
    SELECT 4, 'Jack', 2, 'type2' FROM DUAL UNION ALL 
    SELECT 5, 'John', 3, 'type1' FROM DUAL UNION ALL 
    SELECT 6, 'Joe', 3, 'type2' FROM DUAL 
) 
SELECT 
    company_name, type_1_agent, type_2_agent 
FROM 
    (SELECT company.name company_name, agent.name agent_name, type FROM company JOIN agent ON company.id = agent.company_id) 
    PIVOT (
     MAX(agent_name) agent 
     FOR type IN ('type1' type_1, 'type2' type_2) 
    ) 
ORDER BY 
    company_name 
Смежные вопросы