SQL加入问题,做一些真正错误的自我加入?

时间:2011-06-06 20:08:38

标签: sql join

好的,所以我试图在SQL中获取给定的输出,以列出自定义季度值以及给定激活和终止日期的帐户。我的公司使用不合标准的季度计算,因此我创建了一个与标准月份匹配的自定义季度识别的小模式。查询工作得很好,直到我试图让事情也包括终止季度。

我将把它用作视图并根据结果生成报告。这是迄今为止的查询。我认识到我不是很好的SQL,所以我努力使用最佳实践和易于阅读的代码。请随意批评任何事情,或者建议更有效地实现我的目标。

SELECT ZoneA.ZoneDescription
        ,TrackerA.Zone
        ,MasterListA.Name
        ,SubscriptionsA.ActivationDate
        ,SubscriptionsA.TerminationDate
        ,ParentA.ProductParentType
        ,MONTH(SubscriptionsA.ActivationDate) AS ActivationMonth
        ,MONTH(SubscriptionsA.TerminationDate) AS TerminationMonth
        ,QuartersA.CompanyFiscalQuarter AS ActivationQuarter
        ,QuartersB.CompanyFiscalQuarter AS TerminationQuarter
FROM BalanceTracker.Zone AS ZoneA INNER JOIN
        BalanceTracker.TrackerAccounts AS TrackerA ON ZoneA.ZoneID = TrackerA.Zone INNER JOIN
        BalanceTracker.SweepAccounts AS SweepA ON TrackerA.TrackedAccount = SweepA.SweepAccount INNER JOIN
        Fed.MasterAccountList AS MasterListA ON SweepA.MasterAccountListID = MasterListA.MasterAccountListID INNER JOIN
        Products.Subscriptions AS SubscriptionsA ON MasterListA.MasterAccountListID = SubscriptionsA.SnlId INNER JOIN
        Products.ProductParent AS ParentA ON SubscriptionsA.ProductCode = ParentA.ProductCode INNER JOIN
        Calendar.Quarters AS QuartersA ON SubscriptionsA.ActivationMonth = QuartersA.MonthNumber,
        Products.Subscriptions AS SubscriptionsB INNER JOIN
        Calendar.Quarters AS QuartersB ON SubscriptionsB.TerminationMonth = QuartersB.CompanyFiscalQuarter
ORDER BY TrackerA.Zone, SubscriptionsA.ActivationDate

表格如下:

-Zone:ZoneID(PK) -TrackerAccounts:跟踪账户(PK),区域(FK) -SweepAccounts:SweepAccount(PK,FK on TrackerAccounts),MasterAccountListId(MasterAccountList上的FK) -MasterAccountList:MasterAccountListId(PK) -Subscriptions:SubscriptionId(PK),SnlId(MasterAccountList上的FK),ProductCode(ProductParent上的FK) -ProductParent:ProductCode(PK)

-Quarters:MonthNumber(PK)

3 个答案:

答案 0 :(得分:1)

你的问题是当你说, Products.Subscriptions AS SubscriptionsB你正在进行交叉连接时,它会输出NxN行,其中N是订阅总数。我怀疑你是否需要加入,因为你似乎没有使用该实例中的任何值,这应该可以正常工作:

SELECT ZoneA.ZoneDescription
        ,TrackerA.Zone
        ,MasterListA.Name
        ,SubscriptionsA.ActivationDate
        ,SubscriptionsA.TerminationDate
        ,ParentA.ProductParentType
        ,MONTH(SubscriptionsA.ActivationDate) AS ActivationMonth
        ,MONTH(SubscriptionsA.TerminationDate) AS TerminationMonth
        ,QuartersA.CompanyFiscalQuarter AS ActivationQuarter
        ,QuartersB.CompanyFiscalQuarter AS TerminationQuarter
FROM BalanceTracker.Zone AS ZoneA INNER JOIN
        BalanceTracker.TrackerAccounts AS TrackerA ON ZoneA.ZoneID = TrackerA.Zone INNER JOIN
        BalanceTracker.SweepAccounts AS SweepA ON TrackerA.TrackedAccount = SweepA.SweepAccount INNER JOIN
        Fed.MasterAccountList AS MasterListA ON SweepA.MasterAccountListID = MasterListA.MasterAccountListID INNER JOIN
        Products.Subscriptions AS SubscriptionsA ON MasterListA.MasterAccountListID = SubscriptionsA.SnlId INNER JOIN
        Products.ProductParent AS ParentA ON SubscriptionsA.ProductCode = ParentA.ProductCode INNER JOIN
        Calendar.Quarters AS QuartersA ON SubscriptionsA.ActivationMonth = QuartersA.MonthNumber LEFT JOIN
        Calendar.Quarters AS QuartersB ON SubscriptionsA.TerminationMonth = QuartersB.CompanyFiscalQuarter
ORDER BY TrackerA.Zone, SubscriptionsA.ActivationDate

答案 1 :(得分:1)

为了让我获得可读性而重新格式化...你的第二个“订阅”没有连接条件会创建一个笛卡尔连接...除此之外,你的查询结构看起来很好(整体)

SELECT 
      ZoneA.ZoneDescription
      ,TrackerA.Zone
      ,MasterListA.Name
      ,SubscriptionsA.ActivationDate
      ,SubscriptionsA.TerminationDate
      ,ParentA.ProductParentType
      ,MONTH(SubscriptionsA.ActivationDate) AS ActivationMonth
      ,MONTH(SubscriptionsA.TerminationDate) AS TerminationMonth
      ,QuartersA.CompanyFiscalQuarter AS ActivationQuarter
      ,QuartersB.CompanyFiscalQuarter AS TerminationQuarter
FROM 
   BalanceTracker.Zone AS ZoneA 
      INNER JOIN BalanceTracker.TrackerAccounts AS TrackerA 
         ON ZoneA.ZoneID = TrackerA.Zone 
         INNER JOIN BalanceTracker.SweepAccounts AS SweepA 
            ON TrackerA.TrackedAccount = SweepA.SweepAccount 
            INNER JOIN Fed.MasterAccountList AS MasterListA 
               ON SweepA.MasterAccountListID = MasterListA.MasterAccountListID 
               INNER JOIN Products.Subscriptions AS SubscriptionsA 
                  ON MasterListA.MasterAccountListID = SubscriptionsA.SnlId 
                  INNER JOIN Products.ProductParent AS ParentA 
                     ON SubscriptionsA.ProductCode = ParentA.ProductCode 
                  INNER JOIN Calendar.Quarters AS QuartersA 
                     ON SubscriptionsA.ActivationMonth = QuartersA.MonthNumber
                  INNER JOIN Calendar.Quarters AS QuartersB 
                     ON SubscriptionsA.TerminationMonth= QuartersB.CompanyFiscalQuarter    
ORDER BY 
   TrackerA.Zone, 
   SubscriptionsA.ActivationDate

答案 2 :(得分:1)

猜测最后一个条件可能是QuartersB.MonthNumber上的加入,而不是QuartersB.CompanyFiscalQuarter上的加入:

     Calendar.Quarters AS QuartersB 
         ON SubscriptionsA.TerminationMonth = QuartersB.MonthNumber  

如果你说LEFT JOIN可以是TerminationMonth,你也可以将最后一次加入更改为NULL

SELECT 
      ZoneA.ZoneDescription
    , TrackerA.Zone
    , MasterListA.Name
    , SubscriptionsA.ActivationDate
    , SubscriptionsA.TerminationDate
    , ParentA.ProductParentType
    , MONTH(SubscriptionsA.ActivationDate) AS ActivationMonth
    , MONTH(SubscriptionsA.TerminationDate) AS TerminationMonth
    , QuartersA.CompanyFiscalQuarter AS ActivationQuarter
    , QuartersB.CompanyFiscalQuarter AS TerminationQuarter
FROM 
     BalanceTracker.Zone AS ZoneA  INNER JOIN
     BalanceTracker.TrackerAccounts AS TrackerA 
         ON ZoneA.ZoneID = TrackerA.Zone  INNER JOIN
     BalanceTracker.SweepAccounts AS SweepA 
         ON TrackerA.TrackedAccount = SweepA.SweepAccount  INNER JOIN
     Fed.MasterAccountList AS MasterListA 
         ON SweepA.MasterAccountListID = MasterListA.MasterAccountListID  INNER JOIN 
     Products.Subscriptions AS SubscriptionsA 
         ON MasterListA.MasterAccountListID = SubscriptionsA.SnlId  INNER JOIN 
     Products.ProductParent AS ParentA 
         ON SubscriptionsA.ProductCode = ParentA.ProductCode  INNER JOIN 
     Calendar.Quarters AS QuartersA 
         ON SubscriptionsA.ActivationMonth = QuartersA.MonthNumber  INNER JOIN 
     Calendar.Quarters AS QuartersB 
         ON SubscriptionsA.TerminationMonth = QuartersB.MonthNumber  
ORDER BY 
      TrackerA.Zone 
    , SubscriptionsA.ActivationDate