我有一个大约有200列的表,所以我想知道以下是否可能:
考虑下表,我们称之为 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
由于使用Microsoft SQL Server Management Studio生成脚本,我可以使用大约200列吗?或者这在纯SQL中是否可行?
这是一个棘手的部分:一些没有代码后缀的表格无法搜索,其值在列中。
我一直在研究这个问题,但除了手动操作外我找不到任何其他东西。
更新1 至于我手动定义为“手动输入所有列名称”之前的句子。
由于
答案 0 :(得分: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
答案 1 :(得分:0)
我不确定这是否是一种有效的方法。可能有其他一些方法可以有效地实现它。但是现在我可以考虑为此创建功能。这是
CREATE FUNCTION GetCodeValue(@Id int)
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE @value varchar(100)
SET @value = (SELECT Value from InformationValues WHERE Id=@Id)
return @value;
END
现在编写查询以获取此输出
SELECT PersonId,
GetCodeValue(AgeCode) as AgeCode,
GetCodeValue(NeighbourhoodCode) as AgeCode,
GetCodeValue(DogFlagCode) as DogFlagCode
FROM PersonInformation
答案 2 :(得分:0)
考虑到数据的设置方式,这是一个大量的join
s。这个想法是:
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
之前将其放入视图中。
答案 3 :(得分: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