SQL объединяет несколько таблиц - PullRequest
4 голосов
/ 26 января 2012

Используя Microsoft SQL 2000, я хотел бы объединить несколько таблиц (A, B, C и D) вместе. Я знаю, что таблица А всегда существует. Тем не менее, я знаю только, что существует хотя бы одна из табличных форм (B, C, D).

Можно ли как-нибудь сделать что-то подобное, чтобы выполнить то, что я пытаюсь сделать?

Select * form table a     
If table b exists left Join table b on a.id = b.id    
If table c exists left Join table c on a.id = c.id    
If table d exists left Join table d on a.id = d.id

Ответы [ 4 ]

5 голосов
/ 26 января 2012

Для этого вам нужно проверить представления словаря данных и использовать динамический SQL

declare @myquery varchar(1000)

set @myquery = 'Select * from a '
if exists (select * from sysobjects where xtype='U' and name = 'b')
begin
   set @myquery = @myquery + 'inner join b on b.id = a.id '
end
if exists (select * from sysobjects where xtype='U' and name = 'c')
begin
   set @myquery = @myquery + 'inner join c on c.id = a.id '
end
if exists (select * from sysobjects where xtype='U' and name = 'd')
begin
   set @myquery = @myquery + 'inner join d on d.id = a.id '
end

exec( @myquery)

Я использовал sysobjects, однако вам рекомендуется использовать Представления информационной схемы вместо

И, БОЛЬШОЙ ОТКАЗ ОТ ДИНАМИЧЕСКОГО SQL

Преимущества

  • Это дает гибкость и масштабируемость
  • Это может уменьшить количество строк написанного кода

Недостатки

  • Это может стать очень сложным и трудным для чтения. Подумайте о кавычках, заключенных в кавычки, и других подобных вещах.
  • Это может отрицательно сказаться на стабильности кода. Некоторые ошибки динамического SQL не будут известны до времени выполнения. (Примером этого является то, что вы ссылаетесь на несуществующую таблицу)
  • Динамический код SQL сложнее тестировать, чем эквивалентный статический SQL. Также может оказаться невозможным протестировать все возможные обстоятельства, с которыми может столкнуться ваш динамический SQL, что создает риск, связанный с этим.
  • Провести эффективный анализ влияния на динамический SQL в вашей кодовой базе будет сложнее.
  • Внедрение и неправильное использование SQL - Динамический SQL более подвержен неправильному использованию и неизменно менее безопасен, чем статический SQL
  • Код запросов в Dynamic SQL не подчиняется плану запросов, и поэтому такие оптимизации могут быть пропущены. Таким образом, он может быть медленнее, чем эквивалентный статический SQL
  • Поскольку запрос SQL не известен до времени выполнения, может быть сложнее настроить динамический код SQL (например, определить индексы, которые могут потребоваться для таблицы)
1 голос
/ 26 января 2012

Ниже приведен запрос. Знак * никогда не должен быть частью запроса, поэтому лучше упомянуть имена столбцов.

declare @query varchar(1000)

set @query = 'Select ColumnName from a '
if exists (select Object_ID from sys.tables where name = 'b')
begin
   set @query = @query + 'inner join b on b.id = a.id'
end
if exists (select Object_ID from sys.tables where name = 'c')
begin
   set @query = @query + 'inner join c on b.id = c.id'
end
if exists (select Object_ID from sys.tables where name = 'd')
begin
   set @query = @query + 'inner join d on d.id = a.id'
end

exec( @query)
0 голосов
/ 26 января 2012

Полагаю, вы имеете в виду, если результаты существуют, а не сами таблицы.

SELECT * FROM TABLEA
OUTER JOIN TABLEB ON TABLEA.id = TABLEB.id
OUTER JOIN TABLEC ON TABLEA.id = TABLEC.id
OUTER JOIN TABLED ON TABLEA.id = TABLED.id

вы просто получите пустые значения для столбцов, в которых значение не совпадает.

так что вы можете фильтровать с

WHERE TABLEB.id is not null

и т.д.

0 голосов
/ 26 января 2012

Вы не можете сделать условное соединение таким образом.

Вы можете просто сделать обычное левое соединение.Если ни одна строка не соответствует критериям объединения, эти столбцы будут иметь значение NULL:

Select *
from table a 
left Join table b on a.id = b.id
left Join table c on a.id = c.id
left Join table d on a.id = d.id

. Столбцы b. * Могут быть NULL, или столбцы c. * Могут быть NULL, либо столбцы d. * Могут быть NULL.

Если вам нужно выбрать первый столбец, отличный от NULL, используйте COALESCE:

Select *, COALESCE(b.SOMECOLUMN, c.SOMECOLUMN, d.SOMECOLUMN) AS SOMECOLUMN
from table a 
left Join table b on a.id = b.id
left Join table c on a.id = c.id
left Join table d on a.id = d.id

Как сказали комментаторы, если таблиц не существует, это не сработает.Я думаю, что я бы на самом деле выступил за то, чтобы идти вперед и создавать таблицы, чтобы ваши схемы всегда соответствовали ожиданиям.Динамический SQL - трудная задача для поддержки и отладки, и статический SQL и схемы могут быть опрошены, чтобы гарантировать их соответствие ожиданиям с использованием метаданных (т. Е. Процедура или представление не будут действительными, если таблица отсутствует, а зависимости могут просматриваться явно)

...