题
我已经在Google和Stack Overflow上搜索了我的查询的答案,但是我觉得我缺乏SQL词汇量阻碍了我找到答案,因为我相信这将是一个常见的问题。在我需要阅读的方向上,任何有用的观点都是受欢迎的。
关于这个问题,我试图在Oracle8i中加入三个表,例如,公司表,发票表和作业表发票表和作业表之间没有链接。我希望在一个查询中,我可以链接返回公司所有发票和所有作业的所有三个表,而不返回每个发票的所有作业(请参阅下面我的示例结果)。
我想看看:
Company 1 Invoice 1 Job 1
Company 1 Invoice 2 Job 2
Company 1 Invoice 3 Job 3
我不想看到:
Company 1 Invoice 1 Job 1
Company 1 Invoice 1 Job 2
Company 1 Invoice 1 Job 3
Company 1 Invoice 2 Job 1
Company 1 Invoice 2 Job 2
Company 1 Invoice 2 Job 3
Company 1 Invoice 3 Job 1
Company 1 Invoice 3 Job 2
Company 1 Invoice 3 Job 3
一如既往地感谢您提供的任何帮助。
编辑:
本质上,发票和作业表都有一个公司表关键字段,只是作业和发票表没有直接相互链接。如果实例出现时有2张发票和3个工作,我理想情况下希望它显示,反之亦然:
Company 1 Invoice 1 Job 1
Company 1 Invoice 2 Job 2
Company 1 Job 3
虽然看着这样的问题让我觉得这比我希望的更容易的答案更远。
解决方案
您的要求意味着您的架构有问题。在这种情况下,我的第一个建议是修改你的模式:添加一个 job_id
到 invoice
或一个 invoice_id
到 job
(或N-N关系表 invoice_job
).
如果您不愿意更新架构,则可以使用将进行连接的查询。该 以下查询 基本上会加入 job
和 invoice
一对一:
SELECT c.company_id, ij.job_id, ij.invoice_id
FROM company c
LEFT JOIN (SELECT job_id, invoice_id,
NVL(j.company_id, i.company_id) company_id
FROM (SELECT j.job_id, j.company_id,
row_number() OVER (PARTITION BY company_id
ORDER BY job_id) job_no
FROM job j) j
FULL OUTER JOIN
(SELECT i.invoice_id, i.company_id,
row_number() OVER (PARTITION BY company_id
ORDER BY invoice_id) invoice_no
FROM invoice i) i
ON j.company_id = i.company_id
AND j.job_no = i.invoice_no) ij
ON c.company_id = ij.company_id
这里的连接条件是人为的。如果您删除发票,作业和发票关系可能会更改。
如果这两个表真的不相关,您可能希望以不同的方式显示结果, 例如:
SQL> SELECT cj.company_id, cj.jobs,
2 listagg(i.invoice_id, ',')
3 WITHIN GROUP (ORDER BY i.invoice_id) invoices
4 FROM (SELECT c.company_id,
5 listagg(j.job_id, ',') WITHIN GROUP (ORDER BY job_id) jobs
6 FROM company c LEFT JOIN job j ON c.company_id = j.company_id
7 GROUP BY c.company_id) cj
8 LEFT JOIN invoice i ON cj.company_id = i.company_id
9 GROUP BY cj.company_id, cj.jobs;
COMPANY_ID JOBS INVOICES
----------- ------ --------
1 1,2,3 1,2
不隶属于 StackOverflow