连接两个表而不组合列

时间:2013-08-20 16:06:27

标签: sql sql-server database tsql

我有各种各样的表/视图:InvoiceDetailcontactpartyaddress和{{1} }。

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

party也是id视图中的一列,所以当Invoice子句执行时,它会合并FROM一侧的id字段,并且没有任何内容可供使用与其他Invoice列相关。此表中列的名称也无法更改:

remarks

1 个答案:

答案 0 :(得分:3)

您需要在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需要您的第七个数据,尝试随时添加详细信息。
  • 您加入的表太多了,您不需要加入所有具有外键的内容,只需要为这个确切的查询提取数据。
  • 您的最终加入是一个完整的加入(不是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

编辑:

因为您询问了联接的内容:

  • 加入/内部联接 - 仅接受在两个表中都有数据的行
  • 左连接/左外连接 - 仅获取左表中具有数据的行(未列出的数据),从右侧获取数据(如果可用)
  • 右连接/左外连接 - 与左连接相对(很少使用,因为左连接更常用)
  • 外部联接 - 任一行中的数据在输出中创建数据
  • 不使用/ 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子句的限制。它基本上是一种在更方便的位置(在连接而不是在哪里)指定连接条件的方法。外连接在概念上可以被认为是内部连接,并且在可选表中添加了一个空行(当且仅当没有其他行匹配时才匹配)。