【问题标题】:Select records that are only associated with a record in another table选择仅与另一个表中的记录关联的记录
【发布时间】:2014-08-22 08:17:38
【问题描述】:

不确定标题是否完整地解释了这个场景,所以我会尽可能描述。我使用的是 SQL Server 数据库,有以下 4 个表:

客户

CustomerID   CustomerName
--------------------------
100001       Mr J Bloggs
100002       Mr J Smith

政策

PolicyID  PolicyTypeID  CustomerID
-----------------------------------
100001    100001        100001
100002    100002        100001
100003    100003        100001
100004    100001        100002
100005    100002        100002

政策类型

PolicyTypeID   PolTypeName   ProviderID
-----------------------------------------
100001         ISA           100001
100002         Pension       100001
100003         ISA           100002

供应商

ProviderID    ProviderName
--------------------------
100001        ABC Ltd
100002        Bloggs Plc

这显然是一个精简的版本,实际的数据库包含更多的记录。我要做的是返回仅拥有来自某个提供商的产品的客户列表。所以在上面的例子中,如果我想用这个 SQL 返回与 ABC Ltd 有政策的客户:

SELECT 
    C.CustomerName, P.PolicyID, PT.PolTypeName, Providers.ProviderName
FROM 
    Customers C 
LEFT JOIN 
    Policies P ON C.CustomerID = P.CustomerID
LEFT JOIN 
    PolicyTypes PT ON P.PolicyTypeID = PT.PolicyTypeID
LEFT JOIN 
    Providers PR ON PR.ProviderID = PT.ProviderID
WHERE 
    PR.ProviderID = 100001

它当前将返回客户表中的两个客户。但客户 Mr J Bloggs 实际上也持有 Bloggs Plc 提供的政策。我不想要这个。我只想退回只持有 ABC Ltd 保单的客户,所以我需要的 SQL 应该只退回 Mr J Smith。

希望我已经说清楚了,如果没有请告诉我。

在此先感谢

史蒂夫

【问题讨论】:

  • 旁注:您可以使用 code 按钮来正确格式化 sql 或示例数据。你不需要到处都有------<br />

标签: sql sql-server unique


【解决方案1】:

脏但可读:

SELECT C.CustomerName, P.PolicyID, PT.PolTypeName, Providers.ProviderName
FROM Customers C LEFT JOIN Policies P ON C.CustomerID = P.CustomerID
LEFT JOIN PolicyTypes PT ON P.PolicyTypeID = PT.PolicyTypeID
LEFT JOIN Providers PR ON PR.ProviderID = PT.ProviderID
WHERE PR.ProviderID = 100001 AND C.CustomerName NOT IN (
    SELECT C.CustomerName
    FROM Customers C LEFT JOIN Policies P ON C.CustomerID = P.CustomerID
    LEFT JOIN PolicyTypes PT ON P.PolicyTypeID = PT.PolicyTypeID
    LEFT JOIN Providers PR ON PR.ProviderID = PT.ProviderID
    WHERE PR.ProviderID <> 100001
)

【讨论】:

  • 哈,我们的想法一模一样!
【解决方案2】:

这个想法是您另外对链接到其他提供商的 customerid 执行 NOT IN:

SELECT C.CustomerName, P.PolicyID, PT.PolTypeName, Providers.ProviderName
FROM Customers C LEFT JOIN Policies P ON C.CustomerID = P.CustomerID
LEFT JOIN PolicyTypes PT ON P.PolicyTypeID = PT.PolicyTypeID
LEFT JOIN Providers PR ON PR.ProviderID = PT.ProviderID
WHERE PR.ProviderID = 100001
--NEW PART
AND C.CustomerID NOT IN
(
    SELECT P.CustomerID
    FROM Policies P
    LEFT JOIN PolicyTypes PT ON P.PolicyTypeID = PT.PolicyTypeID
    LEFT JOIN Providers PR ON PR.ProviderID = PT.ProviderID
    WHERE PR.ProviderID <> 100001
)

【讨论】:

  • 大家好,感谢所有建议。我现在可以工作了。 :)
  • 别忘了选择一个答案。任何答案。
  • 我该怎么做?我似乎没有那个选项(我通过手机访问)
  • 您使用的是App还是手机网站?
  • 我正在使用移动网站。等等,是滴答声吗?即我是否将其设为绿色?
【解决方案3】:

试试这个...

SELECT C.CustomerName, P.PolicyID, PT.PolTypeName, Providers.ProviderName 
    from Customers C inner join POLICIES P ON C.CustomerID = P.CustomerID
    inner join PT ON P.PolicyTypeID = PT.PolicyTypeID
    inner join Providers PR ON PR.ProviderID = PT.ProviderID
    where  PR.ProviderID = 100001 and c.CustomerID not in 
    (SELECT C.CustomerID from Customers C 
    inner join POLICIES P ON C.CustomerID = P.CustomerID 
    inner join PT ON P.PolicyTypeID = PT.PolicyTypeID 
    inner join Providers PR ON PR.ProviderID = PT.ProviderID where  PR.ProviderID <> 100001)

【讨论】:

  • 您将其格式化为代码以获得更优雅的外观。见stackoverflow.com/editing-help
  • 大家好,感谢所有建议。我现在可以工作了。 :)
猜你喜欢
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
相关资源
最近更新 更多