2015-11-24 36 views
0

我有一个表结构(我没有设计也不能更改),它使用varchar字段来存储关于实体的属性。我想编写一个SQL查询来特别搜索两个属性,并将多个结果行合并为单个行。为了说明这一点,我的表与此类似:Oracle group by 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' | 
==================================== 

type1type2是硬编码到软件作为有效值(再次,我没有写它),所以对于这些值的搜索应该是成功的(允许为空)。所以,我必须将我的搜索建立在这些值的基础上。

作为一个新手,我可以写这样的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

你可以用透视功能做到这一点,就像这样:

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