Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 根据配置表从数据表中查找相应的值_Sql_Sql Server_Sql Server 2012 - Fatal编程技术网

Sql 根据配置表从数据表中查找相应的值

Sql 根据配置表从数据表中查找相应的值,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有两个表PaymentData和PaymentDataConfig。有一个公共列id。表PaymentDataConfig有一个configColumn,其中包含表PaymentData中的列名称 if exists (select 1 from sys.objects o where o.[object_id] = object_id(N'PaymentData')) begin drop table PaymentData end create table PaymentDat

我有两个表
PaymentData
PaymentDataConfig
。有一个公共列
id
。表
PaymentDataConfig
有一个
configColumn
,其中包含表
PaymentData
中的列名称

if exists (select 1 from sys.objects o where o.[object_id] = object_id(N'PaymentData'))
begin
    drop table PaymentData 
end

create table PaymentData 
(
    id int,
    payment1 decimal(20,2),
    payment2 decimal(20,2),
    payment3 decimal(20,2),
    payment4 decimal(20,2),
    payment5 decimal(20,2)
)

insert into PaymentData (id, payment1, payment2, payment3, payment4, payment5)
select 1 as id, 1001.00 as payment1, 1002.00 as payment2, 1003.00 as payment3, 1004.00 as payment4, 1005.00 as payment5 union all
select 2 as id, 2001.00 as payment1, 2002.00 as payment2, 2003.00 as payment3, 2004.00 as payment4, 2005.00 as payment5 union all
select 3 as id, 3001.00 as payment1, 3002.00 as payment2, 3003.00 as payment3, 3004.00 as payment4, 3005.00 as payment5 union all
select 4 as id, 4001.00 as payment1, 4002.00 as payment2, 4003.00 as payment3, 4004.00 as payment4, 4005.00 as payment5 union all
select 5 as id, 5001.00 as payment1, 5002.00 as payment2, 5003.00 as payment3, 5004.00 as payment4, 5005.00 as payment5

select * from PaymentData

if exists (select 1 from sys.objects o where o.[object_id] = object_id(N'PaymentDataConfig'))
begin
    drop table PaymentDataConfig 
end

create table PaymentDataConfig 
(
    id int,
    configColumn varchar(1000)
)

insert into PaymentDataConfig (id, configColumn)
select 1 as id, 'payment1' as configColumn union all
select 2 as id, 'payment2' as configColumn union all
select 3 as id, 'payment3' as configColumn union all
select 4 as id, 'payment4' as configColumn union all
select 5 as id, 'payment5' as configColumn

select * from PaymentDataConfig

select p.*, c.* 
from PaymentData p 
join PaymentDataConfig c on p.id = c.id 
如果我在id上连接两个表,我将得到如下结果

id  payment1| payment2|payment3 |payment4|  payment5|id |configColumn
------------+---------+---------+--------+----------+---+-------------
1   1001.00 | 1002.00 | 1003.00 | 1004.00|  1005.00 |1  |payment1
2   2001.00 | 2002.00 | 2003.00 | 2004.00|  2005.00 |2  |payment2
3   3001.00 | 3002.00 | 3003.00 | 3004.00|  3005.00 |3  |payment3
4   4001.00 | 4002.00 | 4003.00 | 4004.00|  4005.00 |4  |payment4
5   5001.00 | 5002.00 | 5003.00 | 5004.00|  5005.00 |5  |payment5
预期结果如下所示,在列名中,我希望看到相应的值

id  payment1| payment2|payment3 |payment4|  payment5|id |configColumn|correspondingValue
============|=========|=========|========|==========|===|============|==================
1   1001.00 | 1002.00 | 1003.00 | 1004.00|  1005.00 |1  |payment1    |1001.00
2   2001.00 | 2002.00 | 2003.00 | 2004.00|  2005.00 |2  |payment2    |2002.00
3   3001.00 | 3002.00 | 3003.00 | 3004.00|  3005.00 |3  |payment3    |3003.00
4   4001.00 | 4002.00 | 4003.00 | 4004.00|  4005.00 |4  |payment4    |4004.00
5   5001.00 | 5002.00 | 5003.00 | 5004.00|  5005.00 |5  |payment5    |5005.00

您可以使用CASE表达式来实现这一点:

select p.*, c.*, CASE c.configColumn WHEN N'payment1' THEN p.payment1 WHEN N'payment2' THEN p.payment2 WHEN N'payment3' THEN p.payment3 WHEN N'payment4' THEN p.payment4 WHEN N'payment5' THEN p.payment5 ELSE NULL END AS correspondingValue
from PaymentData p 
join PaymentDataConfig c 
on p.id = c.id 
正如您的更新所提到的,如果您有许多已配置的列,则可以使用动态sql:

DECLARE @SQL nvarchar(max)=N''
DECLARE @ID int;
SELECT @ID=MIN(ID) FROM PaymentDataConfig;
WHILE @ID IS NOT NULL
BEGIN
  SET @SQL=@SQL+' WHEN N''payment''+CAST(@ID AS nvarchar(20)) +N' THEN p.payment'+ CAST(@ID AS nvarchar(20))';
  SELECT @ID=MIN(ID) FROM PaymentDataConfig WHERE ID>@ID;
END
SET @SQL=@SQL+N'
    select p.*, c.*, CASE c.configColumn '+ @SQL + N' ELSE NULL END AS correspondingValue
    from PaymentData p 
    join PaymentDataConfig c 
    on p.id = c.id'

exec sp_executesql @SQL;

您可以使用CASE表达式来实现这一点:

select p.*, c.*, CASE c.configColumn WHEN N'payment1' THEN p.payment1 WHEN N'payment2' THEN p.payment2 WHEN N'payment3' THEN p.payment3 WHEN N'payment4' THEN p.payment4 WHEN N'payment5' THEN p.payment5 ELSE NULL END AS correspondingValue
from PaymentData p 
join PaymentDataConfig c 
on p.id = c.id 
正如您的更新所提到的,如果您有许多已配置的列,则可以使用动态sql:

DECLARE @SQL nvarchar(max)=N''
DECLARE @ID int;
SELECT @ID=MIN(ID) FROM PaymentDataConfig;
WHILE @ID IS NOT NULL
BEGIN
  SET @SQL=@SQL+' WHEN N''payment''+CAST(@ID AS nvarchar(20)) +N' THEN p.payment'+ CAST(@ID AS nvarchar(20))';
  SELECT @ID=MIN(ID) FROM PaymentDataConfig WHERE ID>@ID;
END
SET @SQL=@SQL+N'
    select p.*, c.*, CASE c.configColumn '+ @SQL + N' ELSE NULL END AS correspondingValue
    from PaymentData p 
    join PaymentDataConfig c 
    on p.id = c.id'

exec sp_executesql @SQL;

在上面的示例中,我只显示了五个付款列,但在PaymentData表中有60个这样的列。此表包含500-1000万条记录的值。是否可以标记SQL Server版本?根据请求添加了版本号在上述示例中,我只显示了五个付款列,但表PaymentData中有60个这样的列。此表包含500-1000万条记录范围内的值。是否可以标记SQL Server版本?将版本号添加为requestedI有60个这样的列,像前面提到的那样编写将非常麻烦。动态SQL是一个很好的选项,请注意,您必须启用它,默认情况下它处于关闭状态(并且具有一些安全隐患)。如果您可以重构数据,另一种方法是以4列格式存储数据,这样每个“记录”就有60行,一行ID、PaymentID、PaymentType(Payment1、Payment2等),最后是实际付款。然后查找与配置匹配的付款就在payment.PaymentID=Config.PaymentID和payment.PaymentType=Config.PaymentType之间。您可以使用Pivot或使用矩阵格式报表在SSRS中重建表样式的输出。我有60个这样的列,像前面提到的那样编写会很麻烦。动态SQL是一个很好的选择,请注意您必须启用它,默认情况下它是关闭的(并且有一些安全隐患)。如果您可以重构数据,另一种方法是以4列格式存储数据,这样每个“记录”就有60行,一行ID、PaymentID、PaymentType(Payment1、Payment2等),最后是实际付款。然后查找与配置匹配的付款就在payment.PaymentID=Config.PaymentID和payment.PaymentType=Config.PaymentType之间。您可以使用Pivot或使用矩阵格式报告在SSRS中重建表样式输出。