如何使用连接表的字段值来连接而不是外键

时间:2015-06-10 18:19:22

标签: sql-server tsql join

我有一个新的数据库架构,我需要查询,我无法在JOIN中使用主键获取所需的数据。我没有设计架构,但我必须使用它。我尝试为此创建一个SQLFiddle,但是当我尝试时它一直给我一个网关错误。

基本上我有一个Contacts表,其中包含存储在数据库中的所有联系人。 Contacts表包含两个字段,用于引用联系人链接到的表(供应商和客户端)。 Contact表还包含名为“ContactType”的字段。这链接到另一个定义联系人类型(所有者或员工)的表。

[Client]
ClientID | Name
==============================
1        | Uptown Dining
2        | Downtown Eatery
3        | Midtown Steakhouse

[Vendor]
VendorID | Name
==============================
1        | ABC Produce
2        | DEF Seafood
3        | GHI Meats

[ContactType]
ContactTypeID | Name
==============================
1             | Owner
2             | Employee

[Contact]
ContactID | TableName | TableID | ContactTypeID | FirstName | LastName
========================================================================
    1     | Client    |    1    |       1       | Bob       | Smith
    2     | Vendor    |    1    |       1       | Jill      | Weston
    3     | Vendor    |    1    |       2       | Alice     | Jenkins
    4     | Client    |    2    |       1       | Chris     | Brown
    5     | Vendor    |    3    |       2       | Todd      | Davis

我要做的是获取他们公司所有者的客户联系人列表。这个SQl可以做到这一点。

SELECT 
  Contact.FirstName,
  Contact.LastName
FROM Client
LEFT JOIN Contact
  ON Client.ClientID = Contact.TableID 
  AND Contact.TableName = 'Client' 
  AND Contact.ContactTypeID = 1

这会给我..

Bob Smith
Chris Brown

问题是我不想在AND Contact.ContactTypeID = 1中使用JOIN。我希望能够使用OwnerEmployee代替primary key (1 or 2)ContactType表的JOIN,但我不确定该怎么做这个。请记住限制需要在JOIN中,因为我需要保留WHERE子句来过滤特定客户端。

例如,如果我想查询特定供应商并获取同一行中所有者和员工的列表,该怎么办...

Vendor Name | Owner First | Owner Last | Employee First | Employee Last
============================================================================
ABC Produce |     Jill    |    Weston  |       Alice    |     Jenkins

1 个答案:

答案 0 :(得分:3)

我不确定我是否正确理解您的问题,但如果我正确地阅读它 - 您希望有机会在WHERE子句中明确指定“所有者”或“员工”,而不是{ {1}}或1

也许这就是你要找的东西:

2

编辑:回复您的评论

并非没有变得混乱......您可以使用派生的内联表或视图,但所有这些都是性能杀手。我能想到的性能损害最小(但仍然很丑陋)的方式是这样的:

SELECT 
  Contact.FirstName,
  Contact.LastName
FROM Client
LEFT JOIN Contact
  ON Client.ClientID = Contact.TableID 
  AND Contact.TableName = 'Client' 
LEFT JOIN ContactType ct ON ct.ContactTypeID = Contact.ContactTypeID
-- Now you can use it directly, as below
WHERE ct.Name = 'Owner'