2016-03-18 6 views
0

У меня есть таблица состоит из имени таблицы, например:Как выбрать данные из нескольких таблиц, где имя таблицы является значением из столбца другой таблицы?

TableA

UID TableName CifKey ... 
    1  xxx  12345 
    1  yyy  12345 
    1  xxx  12345 
    2  zzz  45678 

Как я могу выбрать данные из таблиц, имеющих имя же как TableName столбец в таблице А?

Например:

SELECT A.a, B.b 
FROM TableA A 
JOIN ' + @TableName + ' B ON A.Cifkey = B.Cifkey 
WHERE A.uid = @uid AND A.cifkey = @cifkey 

Спасибо!

+0

Если 'UID = 1' и' Cifkey = 12345', что было бы TableName? –

+0

tablename будет xxx и yyy, спасибо! – Snow

+0

Каков первичный ключ таблицы A? – Squirrel

ответ

0

Dynamic SQL это путь:

DECLARE @uid INT = 1, 
     @cifkey INT = 12345 

DECLARE @sql NVARCHAR(MAX) = '' 

SELECT @sql = @sql + 
'SELECT 
    A.a, B.b -- Replace with correct column names 
FROM TableA A 
JOIN ' + QUOTENAME(TableName) + ' B 
    ON A.Cifkey = B.Cifkey 
WHERE 
    A.uid = @uid 
    AND A.cifkey = @cifkey 
UNION ALL 
' 
FROM (
    SELECT DISTINCT TableName FROM TableA WHERE UID = @uid AND cifkey = @cifkey 
) t 

IF @sql <> '' BEGIN 
    -- Remove the last UNION ALL 
    SELECT @sql = LEFT(@sql, LEN(@sql) - 11) 

    PRINT @sql 

    EXEC sp_executesql 
     @sql, 
     N'@uid INT, @cifkey INT', 
     @uid, 
     @cifkey 
END 
+0

Это решение, которое я хочу! Спасибо огромное! Спасибо, ребята :) – Snow

+2

Когда динамическое SQL - единственное решение, у вас часто возникает проблема моделирования базы данных –

+0

Как правило, но не всегда. У Dynamic SQL есть своя польза, уловки - все запросы для одного. –

0

Если ваш присоединиться работы, динамический SQL является, как вы хотите, чтобы выполнить задачу ..

declare @tablename nvarchar(100) 
select @tablename=tablename from yourtable where [email protected] and [email protected] 

declare @sqlquery nvarchar(4000) 
set @sqlquery='SELECT A.a, B.b FROM TableA A 
JOIN ' + @TableName + ' B 
ON A.Cifkey = B.Cifkey 
WHERE A.uid = @uid and A.cifkey = @cifkey'; 

exec sp_executesql @sqlquery, 
N'@uid int,@cifkey int', 
@uid=10,@cifkey=100 
+0

привет, но это будет несколько таблиц, например, когда '@uid = 1' и' @cifkey = 12345', тогда мне нужно выбрать данные из таблицы xxx и таблицы yyy. – Snow

+0

hi, 'select @ tablename = tablename из вашей таблицы, где uid = @ uid и cifkey = @ cifkey', как это Я могу получить только таблицу xxx, не могу получить таблицу yyy. благодаря! – Snow

0

Вы должны будете использовать dyanmic запрос - что-то вроде этого

DECLARE @tablename VARCHAR(50) 
DECLARE @uid INT = 1 
DECLARE @cifkey INT = 12345 
SELECT @tablename = TableName FROM TableA WHERE uid = @uid AND cifkey = @cifkey 

DECLARE @query VARCHAR(500) 

SELECT @query = 'select A.a, B.b from TableA A JOIN ' + @tablename + ' B 
ON A.Cifkey = B.Cifkey 
WHERE A.uid = ' + CONVERT(VARCHAR(20),@uid) + ' and A.cifkey = ' + CONVERT(VARCHAR(20), @cifkey) 

EXEC(@query) 
+0

hi, 'SELECT @tablename = TableName FROM TableA WHERE uid = @uid AND cifkey = @ cifkey' как это Я могу получить только таблицу xxx, не могу получить таблицу yyy. благодаря! – Snow

0

Короче говоря, нет, не так, как вы просите. Вы можете, однако, использовать динамический SQL, как и в this answer создать серию SELECT заявлений, которые могут быть объединены с UNION с для получения желаемых результатов, как это:

SELECT DISTINCT 'SELECT A.a, B.b FROM TableA A 
     JOIN ' + TableName + ' B 
     ON A.Cifkey = B.Cifkey 
     WHERE A.uid = @uid and A.cifkey = @cifkey 
     UNION 
     ' 
FROM TableA 

Просто скопировать результаты в редактор SQL, удалите UNION из последнего предмета и запустите все, чтобы получить ваши результаты.

0

я должен сказать ... это немного сумасшедший

Примечание: Я добавил колонку ID в TableA в качестве первичного ключа. Это необходимо для однозначной идентичности строк в differenciate несколько строк с таким же UID & Cifkey

-- Create the table 
create table TableA 
(
    ID  int identity, 
    UID  int, 
    TableName varchar(5), 
    CifKey  int, 
    a  int 
) 

create table xxx 
(
    CifKey  int, 
    b  int 
) 

create table yyy 
(
    CifKey  int, 
    b  int 
) 

create table zzz 
(
    CifKey  int, 
    b  int 
) 

set nocount on 

-- Insert some sample data 
insert into TableA select 1, 'xxx', 12345, 1 
insert into TableA select 1, 'yyy', 12345, 2 
insert into TableA select 1, 'xxx', 12345, 3 
insert into TableA select 2, 'zzz', 45678, 4 

insert into xxx select 12345, 100 
insert into yyy select 12345, 200 
insert into zzz select 45678, 300 

-- the Dynamic SQL query 
declare @sql nvarchar(max) 

select @sql = N'SELECT A.a, b = COALESCE(' 

select @sql = @sql + 
     + N'B' + convert(varchar(10), ID) + '.b,' 
from TableA 
order by ID 

select @sql = left(@sql, LEN(@sql) - 1) + ')' + char(13) 

select @sql = @sql 
     + N'FROM TableA A' + char(13) 

; with cte as 
(
    select *, rn = convert(varchar(10), ID) 
    from TableA 
) 
select @sql = @sql 
     + N'LEFT JOIN ' + quotename(TableName) + ' AS B' + rn + ' ' + char(13) 
     + N'ON A.CifKey = B' + rn + '.CifKey' + char(13) 
     + N'AND A.ID  = ' + rn + char(13) 
from cte 

print @sql 
exec sp_executesql @sql 

set nocount off 

-- clean up 
drop table TableA 
drop table xxx 
drop table yyy 
drop table zzz 

-- The generated Query (print @sql) 
SELECT A.a, b = COALESCE(B1.b,B2.b,B3.b,B4.b) 
FROM TableA A 
LEFT JOIN [xxx] AS B1 
ON A.CifKey = B1.CifKey 
AND A.ID  = 1 
LEFT JOIN [yyy] AS B2 
ON A.CifKey = B2.CifKey 
AND A.ID  = 2 
LEFT JOIN [xxx] AS B3 
ON A.CifKey = B3.CifKey 
AND A.ID  = 3 
LEFT JOIN [zzz] AS B4 
ON A.CifKey = B4.CifKey 
AND A.ID  = 4 
Смежные вопросы