Sql 根据存储为表上值的列从另一个表中选择值
表1:Sql 根据存储为表上值的列从另一个表中选择值,sql,sql-server,tsql,Sql,Sql Server,Tsql,表1: --------------------------------------- Column_A Column_B --------------------------------------- Test A name Test B address Test C phone 表2: ---------------------
---------------------------------------
Column_A Column_B
---------------------------------------
Test A name
Test B address
Test C phone
表2:
-------------------------------------------------------------------
name address email country phone
-------------------------------------------------------------------
Kush KTM a@a.c NP 98545
第二个表是一个临时表,只能容纳一行 所需输出:
---------------------------------------
Column_A Val
---------------------------------------
Test A Kush
Test B KTM
Test C 98545
我试着旋转第二个表,但由于它将是一个列数动态的表,这将很复杂
还有其他选择吗?这没有意义 您需要在单值PK(主键)或多值(复合键)上创建表a和表B之间的关系。表1将有一个PK到FK(外键) 当A和B都有名称作为值时,现在的输出是什么? 你基本上违反了正常规律 见下文,数据库通常为第三范式 下面是一个更好的解决方案 表1
Test Description Surrogate
---------------------------------------
Test A name 1
Test B address 2
Test C phone 3
Test D name 4
表2
Surrogate Value
---------------------------------------
1 Kush
2 Bush
使用表1(测试/说明)中的代理项与表2中的(值)关联
还有其他方法可以做到这一点,但如果没有书面的业务规则,这是一种方法。在
Table2nd
中具有固定列数的简单案例可以使用unpivot解决:
SELECT a.Column_A, b.colVal
FROM
Table1st a
INNER JOIN
(
SELECT
*
FROM
Table2nd
unpivot (
colVal
for Col in (name, address, email, country, phone)
) unpvt
) b
ON a.Column_B = b.col;
对于Table2nd
没有固定列的一般情况,需要通过动态sql解决,但使用相同的unpivot。看看蓝脚怪是如何做到这一点的
您可以通过多种方式获取Table2nd
的动态列,例如通过sys.columns
,或者如果您假设在Table1st
中指定的列始终存在,则从Table1st:
DECLARE @cols NVARCHAR(100);
SET @cols = STUFF((SELECT distinct ',' + Column_B
FROM Table1st
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
有几个注意事项:
- 为了让unpivot工作,unpivot列的类型都需要相同。如果不是这种情况,请尝试通过
进行强制转换NVARCHAR
- 如果需要使用
,则需要在联接的两侧执行此操作QUOTENAME
declare @query varchar(500) = (select stuff(
(SELECT ',' + B.NAME
from sys.tables A
inner join syscolumns B
on A.[object_id] = B.id
where A.name = 'Table2'
FOR XML PATH('')),1,1,'') A)
set @query = 'select Column_A, Value from Table2 unpivot (Value for V in (' + @query + ')) B
inner join Table1 on Table1.Column_B = B.V'
exec sp_sqlexec @query
第二个表是一个临时表,只能容纳一行。
declare @query varchar(500) = (select stuff(
(SELECT ',' + B.NAME
from sys.tables A
inner join syscolumns B
on A.[object_id] = B.id
where A.name = 'Table2'
FOR XML PATH('')),1,1,'') A)
set @query = 'select Column_A, Value from Table2 unpivot (Value for V in (' + @query + ')) B
inner join Table1 on Table1.Column_B = B.V'
exec sp_sqlexec @query