这可能已经存在,但搜索起来很难理解。基本上,我有一个主表,公司,有一个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。
答案 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)