#sql #sql-server
#sql #sql-сервер
Вопрос:
У меня есть две базы данных на одном сервере sql, и я должен связать две таблицы с одного сервера БД с двумя таблицами на другом сервере БД, чтобы получить необходимую мне информацию. Проблема в том, что когда я пытаюсь связать две таблицы со второго сервера БД, запрос возвращает дубликаты из 1000 или более. Как я могу выполнить один запрос к двум базам данных? Все таблицы имеют общий столбец repair_ord. Кто-нибудь, пожалуйста, может мне помочь? Спасибо.
server 1 = CXADMIN
SERVER 2 = SAADMIN
Вот как пока выглядит мой запрос:
SELECT RF.REPAIR_ORD,
RH.RECV_UNIT,
RH.RECV_SERIAL_NBR,
RP.FAULT_CODE,
RP.REPAIR_ACTION_CODE,
CG.TASK_CODE
FROM CXADMIN.RO_FAILURE_DTL RF,
CXADMIN.RO_HIST RH,
saadmin.sa_repair_part@elgsad rp,
saadmin.sa_code_group_task_dtl@elgsad cg
WHERE RF.REPAIR_ORD = RH.REPAIR_ORD
AND RP.REPAIR_ORD = CG.REPAIR_ORD
AND RF.FAILURE_CODE ='DISK'
AND RH.CURR_FACILITY_ID ='23'
AND RF.CREATED_DATE >'1-JUN-2010'
AND RF.CREATED_DATE < '1-JUL-2010'
AND ( CG.TASK_CODE ='PHMD'
OR CG.TASK_CODE ='PHSN'
OR CG.TASK_CODE ='CHMD'
OR CG.TASK_CODE ='CHSN')
Комментарии:
1. Почему бы вам просто не
UNION ALL
использовать их?2. При использовании соединений возникают дубликаты (в вашем запросе используется синтаксис соединения ANSI-89), поскольку родительская запись имеет более одной дочерней записи. Мы не знаем ваших данных — закомментируйте таблицы и постепенно добавляйте их, чтобы узнать, за что отвечает join.
3. @zerkms, я попробовал функцию объединения, но я не понимаю, как ее использовать в этом запросе, поскольку все таблицы одинаковые. У них просто одинаковый столбец repair_ord.
Ответ №1:
Я думаю, что проблема с дубликатами заключается не в объединении двух баз данных, а скорее в вашем объединении в первую очередь. Я думаю, вам может понадобиться ВНУТРЕННЕЕ или ВНЕШНЕЕ соединение для обработки связывания. Что касается получения данных из двух разных баз данных, синтаксис довольно прост. Вы просто добавляете имя сервера, ставите точку над именем базы данных, ставите точку над именем владельца, ставите точку над именем таблицы.
Например:
SELECT firstdb.*, seconddb.*
FROM Server1.Database1.dbo.myTable AS firstdb
INNER JOIN Server2.Database2.dbo.myTable AS seconddb
ON firstdb.id = seconddb.id
В вашем примере звучит так, как будто вы получаете ссылку для работы, но у вас проблема с соединением в поле repair_ord. Хотя я не знаю вашей схемы, я бы предположил, что эта ссылка должна быть ВНУТРЕННИМ СОЕДИНЕНИЕМ. Если вы просто добавите обе таблицы в инструкцию FROM и не выполните свою инструкцию WHERE должным образом, вы столкнетесь с проблемами, которые вы описываете.
Я бы посоветовал вам упростить эту настройку и поместить ее в тестовую среду (на одной базе данных). Попробуйте объединить четыре таблицы, пока не получите все правильно. Затем добавьте сложности вызовов с несколькими базами данных.
Комментарии:
1. есть предложения по этому поводу? dba.stackexchange.com/questions/102170 /…
Ответ №2:
Если бы вы переписали свое предложение FROM, чтобы использовать ANSI 92, вы бы получили это
FROM CXADMIN.RO_FAILURE_DTL RF
INNER JOIN CXADMIN.RO_HIST RH
ON RF.REPAIR_ORD = RH.REPAIR_ORD
,
saadmin.sa_repair_part@elgsad rp
INNER JOIN saadmin.sa_code_group_task_dtl@elgsad cg
ON RP.REPAIR_ORD = CG.REPAIR_ORD
Затем становится легко видеть, что вы создали декартово произведение между RF join RH
и RP JOIN CG
Вам нужно соединить RF с RP или CG, или RH с RP или CG
например
FROM CXADMIN.RO_FAILURE_DTL RF
INNER JOIN CXADMIN.RO_HIST RH
ON RF.REPAIR_ORD = RH.REPAIR_ORD
INNER JOIN saadmin.sa_repair_part@elgsad rp
ON RF.REPAIR_ORD = RP.REPAIR_ORD
INNER JOIN saadmin.sa_code_group_task_dtl@elgsad cg
ON RP.REPAIR_ORD = CG.REPAIR_ORD
Или, если вы настаиваете на использовании объединений в стиле ANSI-86, вы можете просто добавить AND RF.REPAIR_ORD = RP.REPAIR_ORD
в свое предложение Where