0

我有 3 张桌子。它们是内部连接的。当我选择从所有三个表中进行选择时,我得到一个笛卡尔积。

我使用了 distinct 并且我尝试过与前 1 名交叉应用。前 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
4

1 回答 1

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] 获取第一条记录)

于 2013-03-15T23:19:40.920 回答