0

我有各种要从中提取的表/视图:InvoiceDetailcontactparty和。addressremarks

基本上我需要从remarks表中提取数据,将其与party表关联的唯一方法是访问表的其余部分remarks以引用其id列,该列是表上的外键party

id也是Invoice视图中的一列,因此当FROM子句执行时,它结合了Invoice侧面的 id 字段,并且没有任何东西与其他remarks列相关。此外,不能更改任一表列上的名称:

 SELECT *
FROM Invoice as invoice_view LEFT OUTER JOIN
  Detail as details ON invoice_view.transact = details.transact LEFT OUTER JOIN
  contact AS co_contact ON invoice_view.company = co_contact.party LEFT OUTER JOIN
  contact AS cp_contact ON invoice_view.company = cp_contact.party INNER JOIN
  party as main_party ON invoice_view.party = main_party.party INNER JOIN
  party as pay_party ON invoice_view.pay = pay_party.party INNER JOIN
  party as rec_party ON invoice_view.rec = rec_party.party LEFT OUTER JOIN

  contact as rec_contact ON rec_party.party = rec_contact.party INNER JOIN
  address as rec_address ON rec_contact.party = rec_address.party AND rec_contact.address = rec_address.addresscode LEFT OUTER JOIN
   contact AS pay_contact ON pay_party.party = pay_contact.party INNER JOIN
   adddress AS pay_address ON pay_contact.party = pay_address.party AND pay_contact.address = pay_address.addresscode AND pay_party.party = pay_address.party LEFT OUTER JOIN
 --What I tried to get it working
  remark as cp_remark CROSS JOIN
 party as custom_party

 WHERE
  (   (custom_party.party = pay_party.party) AND (custom_party.id = cp_remark.id)             OR (cp_remark.id IS NULL) OR (custom_party.remark = 0)) 
 --More where statements that have no affect on this
4

1 回答 1

4

您需要为ON您的加入添加一个条件remark并摆脱它CROSS JOIN。例如你可以这样做:

LEFT OUTER JOIN remark as cp_remark ON cp_remark.id = main_party.id OR cp_remark.id = pey_party.id OR cp_remark.id = rec_party.id    

在旁注中,有一些建议:

  • SELECT *除非您正在为自己的消费编写查询,否则不要使用。您的代码应该向您显示您正在使用的数据,仅将其包含在结果集中。
  • 这是个人喜好,但我一直发现将连接放在左侧比放在右侧容易得多。
  • JOIN以更合乎逻辑的方式排序,第二个需要JOIN来自第七个的数据,尝试随时添加细节。
  • 您加入的表太多了,您不需要加入具有外键的所有内容,只需加入您为这个确切查询提取的数据。
  • 您的最终连接是一个完整连接(no ON),后面跟着一个CROSS JOIN(它们是等价的),在大多数情况下,这些都不是一个好主意。这两者都会导致将表的完整结果添加到结果集中。
  • 外键用作指导和数据完整性,它们不定义连接的实际执行方式。
  • 类似命名的列可以通过使用table.column你已经为你的连接做的来解析。

这就是我将如何格式化您的原始版本。(由于我不知道哪些确切的更改最适合您的数据集,因此我没有在此处包含我的建议)

SELECT *
FROM Invoice as invoice_view
LEFT OUTER JOIN Detail as details ON invoice_view.transact = details.transact
INNER JOIN party as main_party ON invoice_view.party = main_party.party
LEFT OUTER JOIN contact AS co_contact ON invoice_view.company = co_contact.party
LEFT OUTER JOIN contact AS cp_contact ON invoice_view.company = cp_contact.party

INNER JOIN party as rec_party ON invoice_view.rec = rec_party.party
LEFT OUTER JOIN contact as rec_contact ON rec_party.party = rec_contact.party
INNER JOIN address as rec_address ON rec_contact.party = rec_address.party
                                 AND rec_contact.address = rec_address.addresscode

INNER JOIN party as pay_party ON invoice_view.pay = pay_party.party
LEFT OUTER JOIN contact AS pay_contact ON pay_party.party = pay_contact.party
INNER JOIN adddress AS pay_address ON pay_contact.party = pay_address.party
                                  AND pay_contact.address = pay_address.addresscode
                                  AND pay_party.party = pay_address.party
--What I tried to get it working                             
LEFT OUTER JOIN remark as cp_remark
CROSS JOIN party as custom_party
WHERE
((custom_party.party = pay_party.party)
  AND (custom_party.id = cp_remark.id)
   OR (cp_remark.id IS NULL)
   OR (custom_party.remark = 0))
 --More where statements that have no affect on this

编辑:

既然您询问了 join 的作用:

  • Join/inner join - 只取两个表中都有数据的行
  • 左连接/左外连接 - 仅获取左侧表中包含数据的行(未列出的行),如果可用则从右侧获取数据
  • 右连接/左外连接 - 与左连接相反(很少使用,因为左连接更常用)
  • 外连接 - 任一行中的数据在输出中创建数据
  • join without as/cross join - 返回两个表之间的每个行组合

例如:

表 A:1,2,3,4
表 B:5,6
交叉连接 A,B:(1,5),(2,5),(3,5),(4,5),(1,6 ),(2,6),(3,6),(4,6)

请注意,内部连接以交叉连接开始,但受ON子句限制。它基本上是一种在更方便的位置(在连接中而不是在哪里)指定连接条件的方法。外连接在概念上可以被认为是内连接,在可选表中添加了一个空白行(当且仅当没有其他行匹配时才匹配)。

于 2013-08-20T16:30:18.927 回答