2012-07-03 2 views
1

У меня есть таблица это называется «Пользователи»Выберите верхний N со всеми соответствующими таблицами

таблица пользователей имеет UserId в качестве первичного ключа, и он является внешним ключом для других 15 таблиц.

Есть ли шаблон запроса, который выберет 200 строк из пользователей и всех связанных таблиц за один снимок? Поэтому мне не нужно будет вводить все остальные 15 таблиц в запросе.

Будет ли запрос динамически находить и выводить столбцы из связанных таблиц?

Он может использовать внутреннее соединение для всех отношений между таблицами.

+0

Можем ли мы привести пример? 1 пользователь, с какими столбцами он должен получить из связанных таблиц – phadaphunk

+0

У меня есть таблицы, такие как Users, UserPictures, UserMessages, UserAddresses и т. Д. У меня бы возник вопрос, например, «select top 200 * из связанных со стороны пользователей» связанных таблиц **, где userid = 1 ", но в разделе" все связанные таблицы "будет динамически. Не печатать вручную. –

+0

Какую базу вы используете? Это, скорее всего, потребует системных таблиц, которые будут различаться между базами данных. –

ответ

2

Я признаю, что это супер уродливое и, вероятно, требуется намного больше работы, но оно основано на генерации базовых запросов на основе отношений PK/FK. Вероятно, вы должны изменить внутреннее соединение влево, если в любой из таблиц FK могут отсутствовать соответствующие записи PK.

declare @table varchar(50); 
set @table = 'Users'; 

declare @pk_table varchar(50); 
declare @fk_table varchar(50); 
declare @pk_column varchar(50); 
declare @fk_column varchar(50); 
declare @curr_table varchar(50); 
set @curr_table = ''; 

declare @sql varchar(8000); 
set @sql = 'select top 200 * from ' + @table + char(10) 
DECLARE table_cursor CURSOR FOR 
SELECT 
    K_Table = FK.TABLE_NAME, 
    FK_Column = CU.COLUMN_NAME, 
    PK_Table = PK.TABLE_NAME, 
    PK_Column = PT.COLUMN_NAME--, 
    --Constraint_Name = C.CONSTRAINT_NAME 
FROM 
    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C 
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK 
    ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME 
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK 
    ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME 
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU 
    ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME 
INNER JOIN (
      SELECT 
       i1.TABLE_NAME, 
       i2.COLUMN_NAME 
      FROM 
       INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1 
      INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 
       ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME 
      WHERE 
       i1.CONSTRAINT_TYPE = 'PRIMARY KEY' 
      ) PT 
    ON PT.TABLE_NAME = PK.TABLE_NAME 
where PK.TABLE_NAME = @table 

OPEN table_cursor 
FETCH NEXT FROM table_cursor INTO @fk_table, @fk_column, @pk_table, @pk_column 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    if @curr_table <> @fk_table 
    begin 
     -- create join 
     set @sql = @sql + ' inner join ' + @fk_table + char(10) 
     set @sql = @sql + ' on ' + @pk_table + '.' + @pk_column + ' = ' + @fk_table + '.' + @fk_column + char(10) 
    end 
    else 
    begin 
     -- create join on fields 
     set @sql = @sql + ' and ' + @pk_table + '.' + @pk_column + ' = ' + @fk_table + '.' + @fk_column + char(10) 
    end 
FETCH NEXT FROM table_cursor INTO @fk_table, @fk_column, @pk_table, @pk_column 
END 

CLOSE table_cursor 
DEALLOCATE table_cursor 

print @sql 
+0

Это круто! Большое спасибо. –

0

Вы можете сделать это следующим образом:

select top 200 columns.... 
from tablename 
inner join table1 .... 
inner join table2 .... 
... 
inner join table15... 

Вам нужно сделать inner join со всеми таблицами, а затем выберите top 200 результаты.

+0

Спасибо. Но, как я уже сказал, я ожидаю, что запрос будет динамически искать и выводить столбцы из связанных таблиц. –

+0

@Teomanshipahi shipahi Что вы подразумеваете под этим? Я не вижу этого в вашем вопросе – phadaphunk

+0

@Teomanshipahi Вы нигде не говорите, может быть, просто в вашей голове: P –

0

This - это то, что вы ищете. Динамический оператор Where. Перейдите к Case statements, чтобы узнать, как использовать случаи в вашем запросе.

0

Есть способ, но это довольно сложно. Вы можете выбрать все имена таблиц и столбцы таблицы из information_schema и построить SQL-запрос с ними.

Нечто подобное должно вам начать работу:

With TableNames 
AS 
(
select * from INFORMATION_SCHEMA.TABLES where table_name like 'User%' 
), 
ColumnNames 
AS 
(
select * 
from INFORMATION_SCHEMA.COLUMNS c 
join TableNames n 
on n.TABLE_NAME=c.TABLE_NAME 
) 
/* Construct SQL query */ 

Вы можете сделать "Exec 'SELECT' + столбцы + 'FROM' + TableName + 'WHERE ..." , а затем выполнить запрос для каждой таблицы.

Смежные вопросы