将联接数据添加到查询结果中

时间:2015-04-14 20:58:13

标签: sql oracle

这可能已经存在,但搜索起来很难理解。基本上,我有一个主表,公司,有一个CompanyID。我必须加入到它的表 - 用户和承包商。公司可能有多个用户,可能有多个承包商。但是用户和承包商彼此没有关系。

我想要的是列出公司的所有用户和所有承包商,例如:

Company1    User1    Contractor1
Company1    User2    Contractor2
Company2    User3    Contractor1
Company2    User4    NULL
Company3    User5    Contractor2
Company3    NULL     Contractor3

等。在上文中,Company1有两个用户和两个承包商,Company2有两个用户和一个承包商,Company3有一个用户和两个承包商。

如果可以在纯粹的单个SQL查询中重新创建,我会感到茫然。如果我使用PHP,那将很容易 - 我只需将它全部拉入数组并创建子数组。但我试图在Logi Info中做到这一点,虽然我到目前为止还无法弄清楚如何在Logi的对象中做到这一点,但我希望也许我可以直接在SQL中做到这一点。

这可能吗?联接通常包括难以清除的重复项;例如,对于Company1,它将有四行,User1-Contractor1,User1-Contractor2,User2-Contractor1和User2-Contractor2。而且我想不出一种分组的方法,因为它需要一个独特的组合(已经存在)或者它会删除错误的东西,例如让User1与两个不同的承包商重复,并完全省略User2。

2 个答案:

答案 0 :(得分:1)

WITH indexed_users AS (
  SELECT u.*, ROW_NUMBER() OVER ( PARTITION BY Company_ID ORDER BY Name ) AS idx
  FROM Users u
),
indexed_contractors AS (
  SELECT c.*, ROW_NUMBER() OVER ( PARTITION BY Company_ID ORDER BY Name ) AS idx
  FROM Contractors c
),
indexed_users_and_contractors AS (
  SELECT COALESCE( u.Company_ID, c.Company_ID ) AS Company_ID,
         u.Name AS UserName,
         c.Name AS ContractorName,
         COALESCE( u.idx, c.idx ) AS idx
  FROM   indexed_users u
         FULL OUTER JOIN
         indexed_contractors c
         ON ( u.Company_id = c.Company_ID
             AND u.idx = c.idx )
  ORDER BY 4
)
SELECT c.Name,
       i.UserName,
       i.ContractorName
FROM   Companies c
       LEFT OUTER JOIN
       indexed_users_and_contractors i
       ON ( c.Company_ID = i.Company_ID )
ORDER BY c.Name, i.idx

<强> SQL Fiddle

|     NAME | USERNAME | CONTRACTORNAME |
|----------|----------|----------------|
| Company1 |    User1 |    Contractor1 |
| Company1 |    User2 |    Contractor2 |
| Company2 |    User3 |    Contractor1 |
| Company2 |    User4 |         (null) |
| Company3 |    User5 |    Contractor2 |
| Company3 |   (null) |    Contractor3 |

答案 1 :(得分:0)

你可以,虽然有点不自然。

SELECT usr.name
      ,cont.name
      ,nvl(usr.comp_id,cont.comp_id)
      ,comp.name
FROM (SELECT id, name, comp_id, row_number() over (partition by comp_id order by id) rn from usr) usr 
FULL OUTER JOIN (SELECT id, name, comp_id, row_number() over (partition by comp_id order by id) rn from cont) cont
  ON (cont.comp_id = usr.comp_id
      AND cont.rn = usr.rn)
JOIN comp
  ON (comp.id = nvl(usr.comp_id,cont.comp_id))
ORDER BY nvl(usr.comp_id,cont.comp_id)