【问题标题】:How to use field value of joined table for join rather than foreign key如何使用联接表的字段值而不是外键进行联接
【发布时间】:2015-06-10 18:19:22
【问题描述】:

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

基本上我有一个联系人表,其中包含存储在数据库中的所有联系人。联系人表包含两个字段,这些字段引用联系人链接到的表(供应商和客户)。 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

问题是我不想在JOIN 中使用AND Contact.ContactTypeID = 1。我希望能够使用OwnerEmployee 代替JOINContactType 表的primary key (1 or 2),但我不确定如何执行此操作。请记住,限制需要在 JOIN 中,因为我需要保留 WHERE 子句来过滤特定的客户端。

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

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

【问题讨论】:

    标签: sql-server tsql join


    【解决方案1】:

    我不确定我是否正确理解了您的问题,但如果我没看错 - 您希望有机会在 WHERE 子句中明确指定“所有者”或“员工”而不是 12

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

    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'
    

    编辑:回复您的评论

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

    SELECT 
      Contact.FirstName,
      Contact.LastName
    FROM Client
    LEFT JOIN Contact
      ON Client.ClientID = Contact.TableID 
      AND Contact.TableName = 'Client' 
      AND Contact.ContactTypeID = (SELECT iix.ContactTypeID FROM ContactType iix WHERE iix.Name = 'Owner')
    

    【讨论】:

    • 你在我想要完成的事情上是正确的。有没有办法在JOIN 而不是WHERE 子句中实现这一点?
    • @webworm 不是很干净。但请看我的编辑。
    猜你喜欢
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 2011-04-12
    • 2021-08-07
    • 1970-01-01
    相关资源
    最近更新 更多