从3个内部连接中选择列 - 仍然获得笛卡尔积。小号

时间:2012-11-15 13:17:36

标签: sql database tsql cartesian

我有3张桌子。他们是内心联合的。当我选择从所有三个表中选择时,我会得到一个笛卡尔积。

我使用了distinct而且我尝试过使用top 1进行交叉应用.Top 1会返回正确数量的记录,但它会重复选择前N个中使用的字段。

基本问题。你能从3个不同的表中选择并避免笛卡尔结果吗?我可以将所有三个表连接起来,并且具有不同的表格,我可以从两个表中获取没有笛卡儿的记录。当我选择从第三个中选择笛卡尔出现的地方时。

如果可以,我应该尝试哪些其他tsql命令/结构? http://imageshack.us/f/255/50353790.png/

 SELECT CRT.[TransactionID]
      ,CRT.[creditrewardsID]
      ,CRT.[OwnerID]
      , CRT.[TransactionDate]
      ,CRT.[ItemID]
      ,CRT.[VALUE]
      ,CRM.First 
      ,CRM.MI 
      ,CRM.Last
      ,CTI.fn
      ,CTI.ln
  FROM [ownership].[dbo].[creditrewardsTransactions] CRT
  Join [ownership].[dbo].[creditrewardsMembers] CRM
    on CRT.creditrewardsid = CRM.[creditrewardsID]
  Join [Exchange].[dbo].[CreditTourInfo] CTI
    on CRM.CRMemberNum  = CTI.PRIMECRPNum
--where CRT.creditrewardsID = 11111

1 个答案:

答案 0 :(得分:0)

要回答您的“基本”问题,是的,您可以轻松加入3个表格而不会收到笛卡尔积。但是,您需要确保具有正确的一对一或一对多连接。

上述问题可能与您在creditrewardsMembers和CreditTourInfo表中的数据有关。加入CRMemberNum和PRIMECRPNum字段可能是多对多连接,这将为您提供笛卡尔积。

您可以运行这些SQL语句进行确认。如果它们都返回记录,那么您就会遇到多对多连接问题。

SELECT CRM.CRMemberNum, COUNT(*)
  FROM [ownership].[dbo].[creditrewardsMembers] CRM
 GROUP BY CRM.CRMemberNum
HAVING COUNT(*) > 1

SELECT CTI.PRIMECRPNum, COUNT(*)
  FROM [Exchange].[dbo].[CreditTourInfo] CTI
 GROUP BY CTI.PRIMECRPNum
HAVING COUNT(*) > 1

如果字段实际上是要加入的正确字段,那么您可能需要从查询中的一个表中选择第一条记录,如下所示。

SELECT CRT.[TransactionID]
      ,CRT.[creditrewardsID]
      ,CRT.[OwnerID]
      ,CRT.[TransactionDate]
      ,CRT.[ItemID]
      ,CRT.[VALUE]
      ,CRM.First 
      ,CRM.MI 
      ,CRM.Last
      ,CTI.fn
      ,CTI.ln
  FROM [ownership].[dbo].[creditrewardsTransactions] CRT
  JOIN [ownership].[dbo].[creditrewardsMembers] CRM
    ON CRT.creditrewardsid = CRM.[creditrewardsID]
  JOIN (
        SELECT PRIMECRPNum, MIN(fn) as [fn], MIN(ln) as [ln]
          FROM [Exchange].[dbo].[CreditTourInfo]
         GROUP BY PRIMECRPNum
       ) CTI
    ON CRM.CRMemberNum  = CTI.PRIMECRPNum

最终,它将取决于您的特定数据模型的限制以及您可能需要做出的权衡。 (即仅从[CreditTourInfo]获取第一条记录)