繁体   English   中英

Select 值来自表名,其中表名存储为使用动态 SQL 的其他表中的列中的值?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM