2017-08-24 95 views
5

我有四个表:文档,项目,文章和DocumentRelations。在文件中有三种类型的文件,这个问题只涉及其中的两个:订单和发票。发票是根据订单生成的。发票可以有多个订单,一个订单可以有多个发票。订单和发票可以有多个项目。表DocumentRelations包含订单和发票之间的关系,该发票是从哪个订单/订单生成的。SQL乘以行。来自同一张表中相邻数据的选择

Documents: 
ID | Name 
-- | -------- 
1 | O/2017/1 
2 | I/2017/1 
3 | O/2017/2 
4 | I/2017/2 
5 | O/2017/3 
6 | O/2017/4 
.. | ... 
99 | X/2017/1 

Ttems: 
ID | ArticleID | DocumentID | Quantity 
-- | --------- | ---------- | -------- 
1 | 1   | 1   | 12 
2 | 1   | 2   | 3 
3 | 2   | 3   | 41 
4 | 2   | 4   | 41 
5 | 1   | 4   | 59 
6 | 1   | 5   | 59 
7 | 3   | 6   | 7 

Articles: 
ID | Name 
-- | ---- 
1 | A 
2 | B 
3 | c 

DocumentRelations: 
OrderID | InvoiceID 
------- | --------- 
1  | 2 
3  | 4 
5  | 4 
8  | 9 
8  | 10 
8  | 11 

方案1:相应的命令/ s到发票/ s不存在。对应的发票/订单/ s不存在。

情景2:对应的发票/订单/ s不包含与发票相同数量的每件物品。相应的发票订单不包含与订单相同数量的每件商品。

这里我的问题开始于: 我需要以容易比较的形式获取每个文档中包含数量的项目列表。因此,订单编号,发票编号,项目名称,订单数量,发票数量。

OrderID | InvoiceID | ItemNameInOrder | QuantityInOrder | QuantityInInvoice 
------- | --------- | --------------- | --------------- | ----------------- 
1  | 2   | A    | 12    | 3 
3  | 4   | B    | 41    | 41 
5  | 4   | A    | 59    | 59 
6  | NULL  | C    | 7    | NULL 
NULL | 7   | B    | NULL   | 11 
8  | 9   | A    | 10    | 9 
8  | 10  | A    | 10    | 9 
8  | 11  | A    | 10    | 19 

如果特定发票的订单不存在,则在名称和数量栏中留空。表DocumentRelations包含三种类型的文档,因此不应出现带有第三种文档的文档。

我的第一个计划是让两个选择返回列,我只需要,每个文档类型。然后根据DocumentRelations中的ID将它们加入。但是,这一切都是倍数。估计结果大约3倍。

SELECT O.ID, I.ID, O.ArticleName, O.Quantity, I.Quantity 
    FROM DocumentRelations R 
LEFT JOIN (SELECT D.ID, D.NumberString, I.Quantity, A.Name 
      FROM Documents D 
      JOIN Items I 
       ON D.ID = I.DocumentID 
      JOIN Articles A 
       ON I.ArticleID = A.ID 
      WHERE D.Name LIKE 'O/%') O 
     ON R.OrderID = O.ID 
LEFT JOIN (SELECT D.ID, , I.Quantity, A.Name 
      FROM Documents D 
      JOIN Items I 
       ON D.ID = I.DocumentID 
      JOIN Articles A 
       ON I.ArticleID = A.ID 
      WHERE D.Name LIKE 'I/%') I 
     ON R.InvoiceID = I.ID 

二类似于第一种,但没有在结束使用DocumentRelations。创建两个选择,一个具有订单ID,项目名称,项目数量和相应发票的ID。其次是发票相同。根据具有相应文档ID的列进行完全外连接来加入它们,但结果相同。

SELECT O.ID, I.ID, O.ArticleName, O.Quantity, I.Quantity 
    FROM (SELECT D.ID, D.NumberString, I.Quantity, A.Name, R.InvoiceID 
      FROM Documents D 
      JOIN Items I 
      ON D.ID = I.DocumentID 
      JOIN Articles A 
      ON I.ArticleID = A.ID 
    LEFT JOIN DocumentRelations R 
      ON D.ID = R.OrderID 
     WHERE D.Name LIKE 'O/%') O 
FULL OUTER JOIN (
     SELECT D.ID, D.NumberString, I.Quantity, A.Name 
      FROM Documents D 
      JOIN Items I 
      ON D.ID = I.DocumentID 
      JOIN Articles A 
      ON I.ArticleID = A.ID 
     WHERE D.Name LIKE 'I/%') I 
    ON O.InvoiceID = I.ID 
+3

这是问题应该怎么样子。考虑添加http://rextester.com模式和数据以获得快速和准确的答案。 – lad2025

+1

准备工作需要一段时间。谢谢你的建议。 – Sonia

+0

第一个查询“Multiples everything”?它看起来对我是正确的。请将您从第一次查询中获得的结果与样本数据一起发布,以便我们可以看到它的错误。第二个查询是绝对错误的。 –

回答

1

我喜欢第二个 - 你只需要对条款ArticleID添加到您的条件 ,你会得到几乎你想要的,只是缺少一些字符串名字。 而且我们认为您不具有两个或更多的线在同一篇文章在一个文件中:

SELECT O.ID, I.ID, O.ArticleName, O.Quantity, I.Quantity 
    FROM (SELECT D.ID, D.NumberString, I.Quantity, A.Name, R.InvoiceID, D.ArticleID 
      FROM Documents D 
      JOIN Items I 
      ON D.ID = I.DocumentID 
      JOIN Articles A 
      ON I.ArticleID = A.ID 
    LEFT JOIN DocumentRelations R 
      ON D.ID = R.OrderID 
     WHERE D.Name LIKE 'O/%') O 
FULL OUTER JOIN (
     SELECT D.ID, D.NumberString, I.Quantity, A.Name, D.ArticleID 
      FROM Documents D 
      JOIN Items I 
      ON D.ID = I.DocumentID 
      JOIN Articles A 
      ON I.ArticleID = A.ID 
     WHERE D.Name LIKE 'I/%') I 
      ON D.InvoiceID = I.ID 
      AND D.ArticleID = I.ArticleID 
+0

我在第二个查询的最后一行发生了错误,应该是O而不是D.不管怎样,'AND O.ArticleID = I.ArticleID'可能解决了它。它给出了与估计结果最接近的结果。我会做几个测试来确认它。 – Sonia