2015-03-19 2 views
-1

У меня есть таблица с около 200 колонн, поэтому мне было интересно, было ли следующее возможно:SQL-запрос для извлечения всех значений для каждого столбца из другой таблицы?

Рассмотрим следующую таблицу, давайте назовем его PersonInformation:

PersonId AgeCode NeighbourhoodCode DogFlagCode ... 
1  5  8     10 
2  1  9     11 
3  5  8     10 

Рассмотрим другую таблицу, давайте называют его InformationValues ​​

Id  Value 
5  21 
1  22 
8  Neighbourhood A 
9  Neighbourhood B 
10  Dog present 
11  Dog not present 

Теперь то, что я хотел бы сделать, это создать представление, которое показывает это:

PersonId AgeCode NeighbourhoodCode DogFlagCode ... 
1  21  Neighbourhood A Dog present 
2  22  Neighbourhood B Dog not present 
3  21  Neighbourhood A Dog present 

Поскольку это может быть сделано из 200 столбцов с помощью Microsoft SQL Server Management Studio с использованием генерирующих скриптов? Или это возможно в простом SQL?

Вот хитрая часть: некоторые таблицы, которые не имеют код суффикса не могут быть найдены и их значение в столбце.

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

Обновление 1 Что касается предложения до того, как я определяю вручную как «вручную ввод всех имен столбцов».

Благодаря

+0

Я думаю * "некоторые таблицы, которые не имеют суффикс кода не могут быть найдены и их значения в столбце. "* неправильно. Может быть, вы хотите сказать «некоторые столбцы, содержащие суффикс кода [...]»? –

+0

Да, это еще один способ поместить его, но те столбцы, которые не имеют суффикса кода, не нуждаются в поиске «истинного значения». – Snowflake

ответ

0

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

CREATE FUNCTION GetCodeValue(@Id int) 
RETURNS VARCHAR(100) 
AS 
    BEGIN 
     DECLARE @value varchar(100) 
     SET @value = (SELECT Value from InformationValues WHERE [email protected]) 
     return @value; 
    END 

Теперь написать запрос, чтобы получить результат, как этот

SELECT PersonId, 
GetCodeValue(AgeCode) as AgeCode, 
GetCodeValue(NeighbourhoodCode) as AgeCode, 
GetCodeValue(DogFlagCode) as DogFlagCode 
FROM PersonInformation 
+1

По соображениям производительности я бы избегал скалярных функций. –

0

Это массивное количество join с, учитывая то, как данные настройки. Идея такова:

select pi.PersonId, iv_age.value as age, 
     iv_nc.value as Neighbourhood, 
     iv_df as DogFlag 
from PersonInformation pi left join 
    InformationValues iv_age 
    on pi.AgeCode = iv_age.id left join 
    InformationValues iv_nc 
    on pi.NeighbourhoodCode = iv_nc.id left join 
    InformationValues iv_df 
    on pi.DogFlagCode = iv_df.id; 

Вы должны иметь возможность продолжать добавлять флаги объединений и добавления для каждого столбца.

Ввод всего этого в боль. Вы можете использовать таблицу information_schema.columns, чтобы получить список столбцов и сгенерировать код либо с помощью инструкции SQL, либо путем отбрасывания имен в электронную таблицу и использования формул электронной таблицы для генерации кода.

SQL Server может обрабатывать такие длинные запросы и количество таблиц. И вы можете поместить это в представление, просто положив create view <viewname> as до select.

1

Вы можете использовать следующий скрипт для создания и выполнения SELECT заявления:

-- Script parameters 
DECLARE @MainTable NVARCHAR(256) 
SET @MainTable = 'dbo.PersonInformation' -- This must be the full name (including the schema name) 
-- End if Script parameters 


DECLARE @Columns NVARCHAR(MAX), @Tables NVARCHAR(MAX) 
SELECT @Columns = '', @Tables = @MainTable + ' maint'; -- Main table 

SELECT @Columns = @Columns + 
     CASE 
      WHEN col.name LIKE '%Code' THEN 
       N', alias' + CONVERT(NVARCHAR(11), col.column_id) + '.[Value] AS ' + QUOTENAME(col.name) 
      ELSE ', maint.' + QUOTENAME(col.name) 
     END, 
     @Tables = @Tables + 
     CASE 
      WHEN col.name LIKE '%Code' THEN 
       CHAR(13) + CHAR(10) + 
       N'LEFT JOIN dbo.InformationValues AS alias' + CONVERT(NVARCHAR(11), col.column_id) + 
       N' ON alias' + CONVERT(NVARCHAR(11), col.column_id) + N'.Id = maint.' + QUOTENAME(col.name) 
      ELSE N'' 
     END 
FROM sys.columns col 
JOIN sys.tables t ON col.object_id = t.object_id 
JOIN sys.schemas s ON t.schema_id = s.schema_id 
WHERE s.name = PARSENAME(@MainTable,2) -- Schema Name 
AND  t.name = PARSENAME(@MainTable,1) -- Table Name 
ORDER BY col.column_id; 

SET @Columns = STUFF(@Columns, 1, 1, N''); 

DECLARE @SqlStatement NVARCHAR(MAX); 
SET @SqlStatement = 
    N'SELECT ' + @Columns + CHAR(13) + CHAR(10) + 
    N'FROM ' + @Tables + 
    N'--WHERE '; -- Maybe you have some filtering conditions 

PRINT @SqlStatement 
-- EXEC(@SqlStatement) 

Над сценарием будет генерировать SELECT заявления, как в следующем примере:

SELECT alias1.[Value] AS [ProductCode], 
    maint.[Name], 
    maint.[ProductNumber], 
    maint.[MakeFlag], 
    maint.[FinishedGoodsFlag], 
    maint.[Color], 
    maint.[Class], 
    maint.[Style], 
    alias19.[Value] AS [ProductSubcategoryCode], 
    alias20.[Value] AS [ProductModelCode], 
    maint.[SellStartDate], 
    maint.[SellEndDate], 
    maint.[DiscontinuedDate], 
    alias24.[Value] AS [rowguCode], 
    maint.[ModifiedDate] 
FROM Production.Product maint 
LEFT JOIN dbo.InformationValues AS alias1 ON alias1.Id = maint.[ProductCode] 
LEFT JOIN dbo.InformationValues AS alias19 ON alias19.Id = maint.[ProductSubcategoryCode] 
LEFT JOIN dbo.InformationValues AS alias20 ON alias20.Id = maint.[ProductModelCode] 
LEFT JOIN dbo.InformationValues AS alias24 ON alias24.Id = maint.[rowguCode]--WHERE 
+0

Uncomment '- EXEC (@SqlStatement)' для выполнения созданного оператора SELECT. –

0

Вы, вероятно, хотите использовать Common Table Expression здесь, конечно, потому что вам придется ссылаться на одну и ту же таблицу много раз.

Должен признаться, что ваш вопрос немного смутил меня - особенно заявление в конце. У меня создается впечатление, что вы хотите рекурсивный поиск, который действительно невозможен без его определения вручную, ведь как вы определяете, хочет ли ваша ссылка и какие данные для скрипта?

Использование CTE должно дать вам гораздо лучшую производительность, чем просто стандартное повторное соединение, это также немного чище. Вот краткий пример:

with CTE as (
    select id, value from cte_data 
) 

select 
    T.Name 
    ,A.Value 
    ,B.Value 
    ,C.Value 
from cte_test T 
    inner join CTE A on A.Id = T.Val1 
    inner join CTE B on B.Id = T.Val2 
    inner join CTE C on C.Id = T.Val3 

Так перевести, что в вашем примере:

with CTE as (
    select id, value from InformationValues 
) 

select 
    PInfo.PersonId 
    ,PInfo.AgeCode 
    ,A.Value as NeighbourhoodCode 
    ,B.Value as DogFlagCode 
from PersonInformation PInfo 
    inner join CTE A on A.Id = PInfo.NeighbourhoodCode 
    inner join CTE B on B.Id = PInfo.DogFlagCode 
Смежные вопросы