Выбор столбцов из 3 внутренних соединений - по-прежнему получается декартово произведение. С

У меня 3 стола. Они соединены внутри. Когда я выбираю выбор из всех трех таблиц, я получаю декартово произведение.

Я использовал отдельные и пробовал перекрестное применение с верхним 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

person user1826685    schedule 15.11.2012    source источник
comment
Не могли бы вы пожалуйста показать нам настоящий запрос (код T-SQL), который вы используете? И да, используя правильные JOIN и правильные условия соединения, вы можете определенно выбрать из трех соединенных таблиц без декартова произведения...   -  person marc_s    schedule 15.11.2012
comment
Можете ли вы также предоставить некоторые образцы данных и результатов? Если вы используете приведенный выше запрос, то вы получаете не декартово, а ожидаемые результаты (при условии, что ваши условия соединения верны). Чтобы помочь больше, нам нужно увидеть данные.   -  person StevieG    schedule 15.11.2012
comment
Для каждой записи в CreditTourInfo я получаю 64 записи. Итак, если у CreditTourInfo 10 записей, я получаю 10 * 64.   -  person user1826685    schedule 15.11.2012
comment
Я не получаю декартово произведение, когда не выбираю из таблицы CTI. Я могу использовать его в соединении, и когда я не выбираю из него какие-либо столбцы, я не получаю слишком много записей.   -  person user1826685    schedule 15.11.2012
comment
По сути, у конкретного человека есть идентификатор кредита в CRT и CRM. У этого же человека есть CRMemberNum в CRM и PRIMECRPNum в CTI. Вот где происходят соединения. Когда я использую предложение where для работы с конкретным человеком... Я вижу, что у этого человека 59 записей в таблице CTI и 64 записи в таблице CRT. Итак, я получаю 3776 записей. Я пытаюсь сгруппировать, но я получаю сообщение об ошибке, и если я не получаю ошибку, я получаю такое же количество записей. Я думаю, мне нужен какой-то другой пункт для ограничения.   -  person user1826685    schedule 15.11.2012
comment
Как я думаю об этом - я думаю, что мне нужно, чтобы кто-то работал с каждой транзакцией в таблице CRT. Пусть они каким-то образом связаны с каждой связанной записью в таблице CTI.   -  person user1826685    schedule 15.11.2012
comment
Вот как это работает. Вам нужно, например, решить, какую из 64 записей в таблице CRT вы хотите видеть. Если вы хотите, чтобы отображалась только одна запись, вам нужно выбрать только одну. Например, в вашем выборе вы выбираете идентификатор участника И идентификатор транзакции. Чтобы это увидеть, вам нужно просмотреть все 64 записи! Если вместо этого вы выберете MAX (идентификатор транзакции), вы увидите только наибольший идентификатор транзакции. Итак, подумайте, что вы на самом деле хотите увидеть... сумму транзакций?   -  person Nick.McDermaid    schedule 19.11.2012


Ответы (1)


Чтобы ответить на ваш «основной» вопрос, да, вы можете легко присоединиться к 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])

person Rob.Kachmar    schedule 15.03.2013