2015-03-19 82 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

我覺得*「沒有代碼後綴不能被搜索和它們的值列一些表。 「* 是錯的。也許你想說的是「一些有代碼後綴[...]的列」? – 2015-03-19 12:52:29

+0

是的,這是放置它的另一種方式,但那些沒有代碼後綴的列不需要查找「真實值」。 – Snowflake 2015-03-19 13:26:29

回答

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

出於性能原因,我會避免標量函數。 – 2015-03-19 12:31:38

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可以處理如此長的查詢和表的數量。你可以通過在select之前放置create view <viewname> as來將其放入視圖。

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

取消註釋' - EXEC(@SqlStatement)'執行生成的'SELECT'語句。 – 2015-03-19 13:28:39

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 
相關問題