[英]SQL - Select Columns from table where another table column value equals column name list
[英]Select value from a table name where table name is stored as a value in column in some other table using dynamic SQL?
我正在尝试获取NULL
列值的值。 相应的值存储在不同的表中。 此表名与我尝试从中获取的表位于同一个表中
ID | ColumnName1 | ColumnName2 | ColumnNam3
____________________________________________
1 ABC TableName1 RecordId1
2 PQR TableName1 RecordID2
3 NULL TableName1 RecordId3
4 NULL TableName2 RecordId1
5 STU TableName2 RecordId2
所以我的 select 查询是
Select ColumnName1 from Table
结果是什么
ID | ColumnName1 | ColumnName2 | ColumnNam3
____________________________________________
1 ABC TableName1 RecordId1
2 PQR TableName1 RecordID2
3 NULL TableName1 RecordId3
4 NULL TableName2 RecordId1
5 STU TableName2 RecordId2
是否有可能实现以下目标?
Select
CASE WHEN ColumnName1 is NULL
then SELECT ColumnName1 From ColumnName2 Where RecordId = ColumnName3
ELSE COlumnName1 AS
ColumnNullFilled END
哦,我已经尝试过动态 sql 之类的
Declare @SqlQuery NVARCHAR(MAX)
SET @SqlQuery = N'Select CASE WHEN ColumnName1 is NULL
then SELECT ColumnName1 From ColumnName2 Where RecordId = ColumnName3
ELSE COlumnName1 AS
ColumnNullFilled1 END
Case when ColumnNameSOmeother is NULL
then SELECT ColumnNameSOmeother From ColumnName2 Where RecordId = ColumnName3
ELSE ColumnNameSOmeother AS
ColumnNullFilled2 END
...
ColumnNameN
FROM Table'
EXEC sp_executesql @SqlQuery;
它不执行,但只打印 columnname2 和 columnname3 而不是 columnvalues。
注意:我创建了一个 SP,它根据 columnname2 和 ColumnName2 作为参数获取记录,它给出了结果,但不适用于动态 SQL。
我还尝试了用户定义的 function,我不确定是否还有其他方法。 这里不仅有 3 条记录,而且我说的是 1000 条记录,如果 null,每条记录在其他表中都有一个值。
抱歉,其他开发人员以前没有进行规范化,我无法返回 go 并更改架构。 此外,如果我不仅针对一列执行此操作,而且针对不同的其他列执行相同的场景,应用程序也会变得过于繁重。 (列名X)。
假设我了解您的要求,您是否可以不只是将两个表都进行外部连接,或者isnull
表中的列都为空,或者用用case
来确定要使用哪一列?
select IsNull(t1.columnName1, t2.columnName1) as Result
from MyTable t
left join Tablename1 t1 on t1.recordId=ColumnNam3
left join Tablename2 t2 on t2.recordId=ColumnNam3
where <criteria>
或者
select case ColumnName2
when 'TableName1' then t1.ColumnName1 else t2.ColumnName1 end as Result
from MyTable t
left join Tablename1 t1 on t1.recordId=ColumnNam3
left join Tablename2 t2 on t2.recordId=ColumnNam3
where <criteria>
尝试以下操作:
(我包含了创建一些测试数据的代码,例如您的示例)
实际的语句生成在底部。
基本上,这会动态生成一个 SQL 语句,该语句在所有引用的表上进行左连接。 但是,请注意,如果左连接有很多并且表中有很多行,那么左连接会导致严重的性能问题。 在这种情况下,我建议重新考虑您的设计。 例如,将列 ColumnName2 & 3 拆分为几列...
-- CREATE TEST DATA
create table [Table] (
[ID] int not null,
[ColumnName1] varchar(16) null,
[ColumnName2] sysname not null,
[ColumnName3] varchar(16) not null
);
go
create table [TableName1] (
[ColumnName1] varchar(16) null,
[RecordId] varchar(16) not null
);
go
create table [TableName2] (
[ColumnName1] varchar(16) null,
[RecordId] varchar(16) not null
);
go
insert into [Table] ( [ID], [ColumnName1], [ColumnName2], [ColumnName3] )
values
( 1, 'ABC', 'TableName1', 'RecordId1' ),
( 2, 'PQR', 'TableName1', 'RecordID2' ),
( 3, NULL, 'TableName1', 'RecordId3' ),
( 4, NULL, 'TableName2', 'RecordId1' ),
( 5, 'STU', 'TableName2', 'RecordId2' );
insert into [TableName1] ( [ColumnName1], [RecordId] )
values
( '111', 'RecordId1' ),
( '222', 'RecordID2' ),
( '333', 'RecordId3' );
insert into [TableName2] ( [ColumnName1], [RecordId] )
values
( 'one', 'RecordId1' ),
( 'two', 'RecordId2' );
go
-- ACTUAL CODE
declare @joinSql nvarchar(max) = N'';
select @joinSql = @joinSql+N'
left join ['+REPLACE([ColumnName2], N']', N'[]]')+N'] on
[base].[ColumnName2] = N'''+REPLACE([ColumnName2], N'''', N'''''')+N''' and
['+REPLACE([ColumnName2], N']', N'[]]')+N'].[RecordId] = [base].[ColumnName3]'
from ( select distinct [ColumnName2] from [Table] ) as [distinct];
declare @caseSql nvarchar(max) = N'';
select @caseSql = @caseSql+N', ['+REPLACE([ColumnName2], N']', N'[]]')+N'].[ColumnName1]'
from ( select distinct [ColumnName2] from [Table] ) as [distinct];
declare @sql nvarchar(max);
set @sql = N'
select
[base].[ID],
COALESCE([base].[ColumnName1]'+@caseSql+N') [ColumnName1],
[base].[ColumnName2],
[base].[ColumnName3]
from [Table] as [base]'+@joinSql+N';';
print @sql;
exec sp_executesql @sql;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.