Проблема с SQL-соединением, что-то действительно не так с самообъединениями? - PullRequest
1 голос
/ 07 июня 2011

Хорошо, поэтому я пытаюсь получить заданный вывод в 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 на TrackerAccounts), MasterAccountListId (FK на MasterAccountList) -MasterAccountList: MasterAccountListId (PK) -Подписки: SubscriptionId (PK), Flcccc (SnlI)ProductCode (FK для ProductParent) -ProductParent: ProductCode (PK)

-Квартиры: MonthNumber (PK)

Ответы [ 3 ]

1 голос
/ 07 июня 2011

Переформатирован для меня, чтобы получить читабельность ... У вас нет условия соединения для ваших вторых "Подписок", которые бы создавали декартово соединение ... Кроме этого, ваша структура запроса выглядит нормально (в целом)

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
1 голос
/ 07 июня 2011

Можно предположить, что последним условием может быть соединение на 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
1 голос
/ 07 июня 2011

Ваша проблема в том, что когда вы говорите , 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...