我有一个小问题,我不确定如何解决 - 我以前从未遇到过。我使用的是MS SQL,并且有一个查询两个表的SQL JOIN查询 - 保险和债权人。保险表包含所有保单细节,而债权人表保存公司详情(保险公司/经纪人姓名等)。
Insurance表包含两个名为CreditorID和BrokerID的外键。这两个外键都与相同的字段相关,即债权人表中的CreditorID字段(因为一些债权人既是保险公司又是保险经纪人)。我不确定如何编写查询。
E.g。保险表可能如下所示:
lInsuranceID lCreditorID lBrokerID mLastPremium dDatePaid sPolicyNumber
1 1 null 1000.00 28/03/2014 12345
2 14 1 2000.00 17/03/2014 67891
债权人表可能如下所示:
lCreditorID sCreditorName
1 Frank's Insurance COMPANY
14 Frank's Insurance BROKER
所以问题是,当我检索特定属性的信息时,我需要从Creditor表中提取两次信息 - 一次使用Insurance.CreditorID = Creditor.CreditorID,再次使用Insurance.CreditorID = Creditor.BrokerID。 / p>
但我不知道如何在一次加入中做到这一点。我试过这个,但它没有用(我得到的错误是" Creditor.sCreditorName"无法绑定:
SELECT Insurance.sPolicyNumber,
Insurance.dDatePaid,
Insurance.dRenewal,
Insurance.mLastPremium,
Creditor.sCreditorName
FROM Insurance
INNER JOIN Creditor cred ON Insurance.lCreditorID = cred.lCreditorID
INNER JOIN Creditor cred1 ON Insurance.lBrokerID = cred1.lCreditorID
WHERE Insurance.lOwnersCorporationID = '1'
有什么建议吗?
修改 好的,谢谢所有的提示,窥视。我将查询修改为看起来像这样,它似乎正在工作(我就是这样一个JOIN noob。即使它有效,我也不确定为什么)
SELECT Insurance.sPolicyNumber, Insurance.dDatePaid, Insurance.dRenewal, Insurance.mLastPremium, cred.sCreditorName as Company, cred1.sCreditorName as Broker
FROM Insurance
LEFT JOIN Creditor cred ON Insurance.lCreditorID = cred.lCreditorID
LEFT JOIN Creditor cred1 ON Insurance.lBrokerID = cred1.lCreditorID
WHERE Insurance.lOwnersCorporationID = '1'
答案 0 :(得分:0)
我认为你想要的是这样的
SELECT Insurance.sPolicyNumber,
Insurance.dDatePaid,
Insurance.dRenewal,
Insurance.mLastPremium,
cred.sCreditorName AS Creditor,
cred1.sCreditorName AS Broker
FROM Insurance
INNER JOIN Creditor cred ON Insurance.lCreditorID = cred.lCreditorID
INNER JOIN Creditor cred1 ON Insurance.lBrokerID = cred1.lCreditorID
WHERE Insurance.lOwnersCorporationID = '1'
我添加了SQLFiddle example来演示(减去select语句中不存在于示例表中的列)。这会使用您的原始查询,但请参阅下面的另一个LEFT OUTER JOIN
示例。
修改强>
如下所述,LEFT JOIN
会很有用,因此您不会过滤BrokerID
为NULL
的行。更新了SQLFiddle上的示例以显示此内容。
答案 1 :(得分:0)
也许左连接可能有帮助?由于您可能在所有实例中都没有Broker ID。
SELECT Insurance.sPolicyNumber,
Insurance.dDatePaid,
Insurance.dRenewal,
Insurance.mLastPremium,
Creditor.sCreditorName
FROM Insurance
INNER JOIN Creditor cred ON Insurance.lCreditorID = cred.lCreditorID
LEFT JOIN Creditor cred1 ON Insurance.lBrokerID = cred1.lCreditorID
WHERE Insurance.lOwnersCorporationID = '1'
答案 2 :(得分:0)
您只需要在SELECT表达式列表中使用表别名:
SELECT i.sPolicyNumber,
i.dDatePaid,
i.dRenewal,
i.mLastPremium,
c.sCreditorName,
b.sCreditorName
FROM Insurance i
LEFT JOIN Creditor c ON c.lCreditorID = i.lCreditorID
LEFT JOIN Creditor b ON b.lCreditorID = i.lBrokerID
WHERE Insurance.lOwnersCorporationID = '1'
请注意,我切换到LEFT OUTER JOIN。这是因为您已经证明引用值可能是NULLable。如果您不使用OUTER JOIN,您将从Insurance表中删除行,我认为这对您不利。
答案 3 :(得分:0)
SELECT Insurance.sPolicyNumber,
Insurance.dDatePaid,
Insurance.dRenewal,
Insurance.mLastPremium,
-- the changed columns
cred.sCreditorName AS CREDITOR,
cred1.sCreditorName AS BROKER,
FROM Insurance
INNER JOIN Creditor cred ON Insurance.lCreditorID = cred.lCreditorID
LEFT OUTER JOIN Creditor cred1 ON Insurance.lBrokerID = cred1.lCreditorID
WHERE Insurance.lOwnersCorporationID = '1'
当您使用Alias(cred和cred1)引用该表时,您必须在列列表中使用别名
答案 4 :(得分:0)
在原始查询中,您将引用“Creditor.sCreditorName”,但是您在联接中使用了别名。
另外,如果FK为空,则使用内部联接,这可能会导致一些条目。例如,您的lInsuranceID = 1的条目将被遗漏。
正确的查询可能是
SELECT ins.sPolicyNumber,
ins.dDatePaid,
ins.dRenewal,
ins.mLastPremium,
cred.sCreditorName as CreditorName,
brok.sCreditorName as BrokerName
FROM Insurance ins
LEFT JOIN Creditor cred ON ins.lCreditorID = cred.lCreditorID
LEFT JOIN Creditor brok ON ins.lBrokerID = brok.lCreditorID
WHERE ins.lOwnersCorporationID = '1'
MSSQL中的一些测试:
declare @Insurance table
(
lInsuranceID int,
lCreditorID int,
lBrokerID int,
mLastPremium money,
dDatePaid date,
sPolicyNumber int
)
INSERT INTO @Insurance
(lInsuranceID, lCreditorID, lBrokerID, mLastPremium, dDatePaid,
sPolicyNumber)
SELECT 1, 1, null, 1000.00, '2014-03-28', 12345
UNION ALL
SELECT 2, 14, 1, 2000.00, '2014-03-17', 67891
declare @Creditor table
(
lCreditorID int,
sCreditorName varchar(64)
)
INSERT INTO @Creditor
(lCreditorID, sCreditorName)
SELECT 1, 'Frank''s Insurance COMPANY'
UNION ALL
SELECT 14, 'Frank''s Insurance BROKER'
SELECT ins.sPolicyNumber,
ins.dDatePaid,
ins.mLastPremium,
brok.sCreditorName as BrokerName,
cred.sCreditorName as CreditorName
FROM @Insurance ins
LEFT JOIN @Creditor cred on cred.lCreditorID = ins.lCreditorID
LEFT JOIN @Creditor brok on brok.lCreditorID = ins.lBrokerID