SQL - нет вывода из правого соединения

У меня есть одна таблица, которую я выбираю с помощью кода: Код A

Select TDS, TL, IK
From (Select Sheet1.TOOLING_DATA_SHEET As TDS, Sheet1.CUTTING_TOOL As TL, ENT_ITEM_MASTER.ITEM_KEY As IK
        From Sheet1
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_CODE=Sheet1.CUTTING_TOOL And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As A

Вывод:

TDS                     TL          IK
TDS-1980D-10+OP10+S7    TL-000032   1
TDS-1980D-10+OP10+S7    TL-000019   34
TDS-2258-01+OP10+S4     TL-000016   53
TDS-2325PU+OP10+S1      TL-000036   7
TDS-1234-56-78          TL-000123   45

и еще одна таблица, которую я выбираю с кодом: Код B

Select ENT_LINK_OBJECTS.OBJ_NAME, ENT_ITEM_MASTER.ITEM_CODE, ENT_ITEM_MASTER.ITEM_KEY
        From ENT_LINK_OBJECTS
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_KEY=ENT_LINK_OBJECTS.ENTITY_KEY And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As B

Вывод:

OBJ_NAME                 ITEM_CODE   ITEM_KEY
TDS-1980D-10+OP10+S7    TL-000032      1
TDS-1980D-10+OP10+S7    TL-000019      34
TDS-2258-01+OP10+S4     TL-000032      28
TDS-2258-01+OP10+S4     TL-000016      53
TDS-2325PU+OP10+S1      TL-000036      7
TDS-2325PU+OP10+S1      TL-000009      9

У меня есть левое соединение таблиц в рабочем коде, который дает мне все, что есть в таблице A, чего нет в таблице B.

Теперь я пытаюсь правильно присоединиться к таблицам, что даст мне все, что есть в таблице B, чего нет в таблице A. Прямо сейчас на выходе ничего нет.


Полный код для Right Join:

Select TDS, TL, IK
From (Select Sheet1.TOOLING_DATA_SHEET, Sheet1.CUTTING_TOOL, ENT_ITEM_MASTER.ITEM_KEY
        From Sheet1
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_CODE=Sheet1.CUTTING_TOOL And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As A
Right Join (Select ENT_LINK_OBJECTS.OBJ_NAME As TDS, ENT_ITEM_MASTER.ITEM_CODE As TL, ENT_ITEM_MASTER.ITEM_KEY As IK
        From ENT_LINK_OBJECTS
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_KEY=ENT_LINK_OBJECTS.ENTITY_KEY And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As B
On A.TOOLING_DATA_SHEET=B.TDS
Where A.TOOLING_DATA_SHEET is Null

Текущий выход:

TDS    TL    IK

Желаемый результат: (все в B, чего нет в A)

TDS                       TL           IK
TDS-2258-01+OP10+S4     TL-000032      28
TDS-2325PU+OP10+S1      TL-000009      9

Я могу добавить свой рабочий код для моего левого соединения, если это полезно. Я также попытался переключить области выбора, выполнить левое соединение и изменить оператор Null, чтобы попытаться выполнить левое соединение, которое также не дает вывода.

ИЗМЕНИТЬ:

Как мой код работает с левым соединением:

Select TDS, TL, IK
From (Select Sheet1.TOOLING_DATA_SHEET As TDS, Sheet1.CUTTING_TOOL As TL, ENT_ITEM_MASTER.ITEM_KEY As IK
        From Sheet1
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_CODE=Sheet1.CUTTING_TOOL And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As A
Left Join (Select ENT_LINK_OBJECTS.OBJ_NAME, ENT_ITEM_MASTER.ITEM_CODE, ENT_ITEM_MASTER.ITEM_KEY
        From ENT_LINK_OBJECTS
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_KEY=ENT_LINK_OBJECTS.ENTITY_KEY And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As B
On A.TDS=B.OBJ_NAME
Where B.OBJ_NAME is Null

ВЫВОД: (все в A, чего нет в B)

TDS                  TL        IK
TDS-1234-56-78     TL-000123   45

person user4888    schedule 02.07.2015    source источник
comment
TDS, TL и IK — это имена столбцов с пустой стороны соединения, которые будут нулевыми. Вместо этого вам нужно вытащить OBJ_Name, Item_COde и Item_Key. например. SELECT OBJ_NAME, ITEM_CODE, ITEM_KEY вместо Select TDS,TL,IK Если я прав, ваш текущий вывод может отображаться пустым, но он показывает 2 пустых строки!   -  person xQbert    schedule 02.07.2015
comment
Это казалось блестящим решением, и я думаю, что в конечном итоге это мне очень поможет, спасибо. К сожалению, на выходе по-прежнему ничего @xQbert . Я изменил свой код в вопросе, если бы вы могли проверить и убедиться, что я выполнил то, что вы имели в виду.   -  person user4888    schedule 02.07.2015
comment
Это потому, что @tirma прав, критериев присоединения недостаточно. поскольку TDS и obj_name совпадают, все записи, включая 28 и 29, удаляются. Вам нужно добавить AND A.TL=B.Item_Code and A.IK = B.Item_key к правильным критериям присоединения   -  person xQbert    schedule 02.07.2015
comment
Я не знаю, почему тогда мне это не понадобилось в моем рабочем левом соединении. Куда бы я их добавил? Я пытаюсь добавить их в свой оператор on после right join, но, очевидно, B еще не определен, поэтому я не знаю, куда его поместить @xQbert   -  person user4888    schedule 02.07.2015
comment
Они понадобятся вам в левом соединении, если у вас есть данные (или их отсутствие), которые вызовут аналогичные проблемы. Проще говоря, вы ДОЛЖНЫ присоединиться к данным, которые делают записи УНИКАЛЬНЫМИ, иначе вы получите дополнительные записи, которые вам, вероятно, не понадобятся, или, в этом случае, удалите записи, которые вам не нужны. Сам по себе TDS не уникален. TDS с TL может быть, но TDS с TL и IK ЯВЛЯЮТСЯ уникальными на основе представленных данных.   -  person xQbert    schedule 02.07.2015
comment
см. ответ ниже о том, как я буду писать, используя правое соединение.   -  person xQbert    schedule 02.07.2015
comment
Однако я говорю, что у меня есть левое соединение, которое работает правильно. Поэтому я не знаю, почему бы не сделать Right Join. Я добавил код для моего рабочего левого соединения выше, если это имеет какое-либо значение @xQbert   -  person user4888    schedule 02.07.2015
comment
причина, по которой ваше левое соединение работает, заключается в том, что у вас нет данных, из-за которых оно не будет работать в ваших примерах... добавьте TDS-1234-56-78 TL-000124 46 в таблицу A и TDS-1234-56-78 TL-000123 45 в таблицу B, и ваше левое соединение перестанет работать правильно. Другими словами, ваши левые соединения работают, потому что у вас, к счастью, нет данных, которые дали бы вам неверные результаты! Обычно левый и правый критерии соединения ДОЛЖНЫ быть одинаковыми. вы просто НЕ ДОЛЖНЫ иметь то же самое из-за ваших данных на этот раз.   -  person xQbert    schedule 02.07.2015


Ответы (3)


--- У вас две проблемы

  1. Поскольку вы хотите, чтобы все записи из B не находились в A. Вам нужно отобразить столбцы таблицы B
  2. Ваши критерии присоединения не учитывают количество уникальных записей. 28 и 9 удаляются, поскольку TDS-2258-01+OP10+S4 и TDS-2325PU+OP10+S1 существуют в таблице A. Проблема в том, что TDS-2258-01+OP10+S4 TL-000032 не существует в А также TDS-2325PU+OP10+S1 TL-000009. Критерии, которые вы используете для ПРИСОЕДИНЕНИЯ, неверны. Чтобы узнать ПРАВИЛЬНЫЕ значения, вам нужно указать связь между таблицами или просто (на основе отображаемых данных) использовать On A.TDS=B.OBJ_NAME and A.TL = B.Item_Code and A.IK = B.Item_key

Значение конечного результата будет:

Select B.TDS, B.TL, B.IK
From (Select Sheet1.TOOLING_DATA_SHEET, Sheet1.CUTTING_TOOL, ENT_ITEM_MASTER.ITEM_KEY
        From Sheet1
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_CODE=Sheet1.CUTTING_TOOL And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As A
Right Join (Select ENT_LINK_OBJECTS.OBJ_NAME As TDS, ENT_ITEM_MASTER.ITEM_CODE As TL, ENT_ITEM_MASTER.ITEM_KEY As IK
        From ENT_LINK_OBJECTS
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_KEY=ENT_LINK_OBJECTS.ENTITY_KEY And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As B
On A.TDS=B.OBJ_NAME
and A.TL = B.Item_Code
and A.IK = B.Item_ke
Where A.TOOLING_DATA_SHEET is Null

Если вы RDBMS поддерживает MINUS (ИСКЛЮЧАЯ SQL SERVER), это также будет работать

(SELECT ENT_LINK_OBJECTS.OBJ_NAME As TDS, 
   ENT_ITEM_MASTER.ITEM_CODE As TL, 
   ENT_ITEM_MASTER.ITEM_KEY As IK
 FROM ENT_LINK_OBJECTS
 INNER JOIN ENT_ITEM_MASTER
   ON ENT_ITEM_MASTER.ITEM_KEY=ENT_LINK_OBJECTS.ENTITY_KEY 
  AND ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As B
EXCEPT 
(SELECT Sheet1.TOOLING_DATA_SHEET, 
        Sheet1.CUTTING_TOOL, 
        ENT_ITEM_MASTER.ITEM_KEY
 FROM Sheet1
 INNER JOIN ENT_ITEM_MASTER
   ON ENT_ITEM_MASTER.ITEM_CODE=Sheet1.CUTTING_TOOL 
  AND ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null)  A

В основном это говорит о том, что возьмите набор результатов B и вычтите из него набор результатов A., что оставит вас с... двумя записями, которые вам нужны. Это работает, только если все столбцы совпадают. Внешние соединения или существует/не существует обеспечивают большую гибкость.

Наглядное пособие по соединениям для лучшего понимания

person xQbert    schedule 02.07.2015
comment
Я поддерживаю этот ответ. Я не нахожу недостатков между добавленными критериями соединения и использованием правильных имен столбцов. - person xQbert; 02.07.2015
comment
Я лично не вижу ничего плохого в этом ответе. Я действительно думаю, что вам нужно EXCEPT, а не минус, поскольку я считаю, что операция находится в SQL Server, и я не думаю, что MINUS работает там, я думаю, что EXCEPT является альтернативой. - person Christian Barron; 02.07.2015

Из того, что вы описываете в комментариях, вы ищете Not Exists, а не Right Join. Правильное соединение даст вам все, что есть в таблице B, плюс все, что совпадает с таблицей A.

Команда Not exists найдет в таблице B все, чего нет в таблице A. Вам нужно что-то вроде следующего:

Select ENT_LINK_OBJECTS.OBJ_NAME, e1.ITEM_CODE, e1.ITEM_KEY
        From ENT_LINK_OBJECTS
        Inner Join ENT_ITEM_MASTER e1
        On e1.ITEM_KEY=ENT_LINK_OBJECTS.ENTITY_KEY And e1.USER_LAST_MODIFIED Is Not Null
        Where not exists
        (Select *
        From Sheet1
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_CODE=Sheet1.CUTTING_TOOL And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null
        where ENT_ITEM_MASTER.ITEM_KEY = e1.ITEM_KEY)
person Christian Barron    schedule 02.07.2015
comment
Здесь работает правое соединение. из-за того, что предложение where возвращает только те записи, которые имеют значение NULL в A. Проблема в двух случаях: 1, возвращаемые столбцы взяты из неправильной таблицы и 2, критерии соединения недостаточны для количественной оценки уникальной записи. 28 и 9 удаляются, поскольку TDS-2258-01+OP10+S4 и TDS-2325PU+OP10+S1 существуют в таблице A. - person xQbert; 02.07.2015
comment
Да, хороший момент, когда я думаю об этом, Right Join сработает. Однако не существует лично мне кажется лучшим решением. - person Christian Barron; 02.07.2015
comment
В зависимости от движка, ключей, индексов... это может быть быстрее, но и то, и другое работает эффективно. Минус должен быть самым быстрым, за которым следует не существует, за которым следует правое соединение, но лишь незначительно быстрее - person xQbert; 02.07.2015
comment
Да, это очень зависит от этих факторов, и я полагаю, что это также зависит от личных предпочтений и от того, что легче всего прочитать разработчику. - person Christian Barron; 02.07.2015
comment
Это кажется отличным решением. И да, мое правое соединение будет работать, потому что это не полное правильное соединение, оно устанавливает A равным нулю. Я пытался сделать правое соединение (с нулями), потому что у меня уже есть работающее левое соединение (с нулями), и я надеялся написать аналогичный код для всех, кто его использует, легко понять. Я попробовал ваше решение и получил сообщение об ошибке: сбой при преобразовании значения varchar «TL-000212» в тип данных int. TL-000212 отсутствует в листах, с которыми я пытаюсь работать, поэтому я не знаю, откуда эта ошибка. Идеи? @КристианБаррон - person user4888; 02.07.2015
comment
@ user4888 попробуйте обновление, которое, надеюсь, избавит вас от ошибки - person Christian Barron; 02.07.2015
comment
@ChristianBarron хм, похоже, отличный код, но на выходе ничего нет. Я в тупике, почему это не сработает... Есть идеи? - person user4888; 02.07.2015
comment
@ChristianBarron Я также отредактировал свой вопрос, включив в него мое рабочее левое соединение (с нулями), если это вообще полезно - person user4888; 02.07.2015
comment
@user4888 user4888 Да, это было запутано из-за имени поля. Обновление должно работать, дайте мне знать, если это не так. - person Christian Barron; 02.07.2015

Проблема кажется легкой. Вы сказали нам: ЭТО даст мне все, что есть в Таблице Б, чего нет в Таблице А.

Но в ожидаемом результате вы сказали нам, что TDS-2258-01+OP10+S4 должен быть в выходных данных, и эта строка не находится в таблице A, поэтому ее не будет в выходных данных.

Я думаю, вы хотели сделать объединение по полю ITEM_KEY и IK вместо использования A.TDS=B.OBJ_NAME

Также в выводе вы должны показать OBJ_NAME, ITEM_CODE и ITEM_KEY вместо TDS,TL,IK

Это последний запрос:

Select OBJ_NAME, ITEM_CODE, ITEM_KEY
From (Select Sheet1.TOOLING_DATA_SHEET As TDS, Sheet1.CUTTING_TOOL As TL, ENT_ITEM_MASTER.ITEM_KEY As IK
        From Sheet1
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_CODE=Sheet1.CUTTING_TOOL And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As A
Right Join (Select ENT_LINK_OBJECTS.OBJ_NAME, ENT_ITEM_MASTER.ITEM_CODE, ENT_ITEM_MASTER.ITEM_KEY
        From ENT_LINK_OBJECTS
        Inner Join ENT_ITEM_MASTER
        On ENT_ITEM_MASTER.ITEM_KEY=ENT_LINK_OBJECTS.ENTITY_KEY And ENT_ITEM_MASTER.USER_LAST_MODIFIED Is Not Null) As B
On A.IK=B.ITEM_KEY
Where A.TDS is Null
person Tirma    schedule 02.07.2015
comment
Нет, потому что при правильном соединении, насколько я понимаю, вы устанавливаете все в таблице A как NULL. Таким образом, все, что пересекается между А и В, и все в А удаляется. A имеет ключи элементов: 1, 34, 53, 7 и 45. B имеет ключи элементов: 1, 34, 28, 53, 7 и 9. Все в A удаляется и все, что перекрывается. Итак, из B: 1, 34 и 7 удаляются, остаются 28 и 9. Правильно? - person user4888; 02.07.2015
comment
@ user4888 ваше понимание правильных соединений неверно. Вы после чего-то совершенно другого - person Christian Barron; 02.07.2015
comment
IK = Item_Code?!? IK = 1 Item_Code = TL-000032 не знаю, как эти двое когда-нибудь сравняются. - person xQbert; 02.07.2015
comment
@ChristianBarron Я изучаю Right Joins из того, что нахожу в Google и здесь, в основном, так что это может быть совершенно неправильно. Тем не менее, я делаю то же самое с левым соединением, которое, как я узнал до сих пор, невероятно похоже, чтобы получить все, что есть в таблице A, чего нет в таблице B, и это работает правильно. Мое разочарование заключается в том, что я не понимаю, как я не могу просто перевернуть их с легкостью. Какие-либо предложения? - person user4888; 02.07.2015
comment
@Tirma, IK - это ITEM_KEY. ITEM_KEY и ITEM_CODE не будут равны друг другу - person user4888; 02.07.2015
comment
извини @user4888, я ошибся. Пожалуйста, проверьте запрос, как я сказал. - person Tirma; 02.07.2015