根据存储为表中值的列从另一个表中选择值

时间:2014-02-03 22:57:47

标签: sql sql-server tsql

表1:

---------------------------------------
    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

我试过转动第二张表,但由于它将是具有动态列数的表格,因此会很复杂。

还有其他选择吗?

3 个答案:

答案 0 :(得分:3)

Table2nd中具有固定列数的简单案例可以通过以下方式解决:

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;

Fiddle here

您没有Table2nd固定列的一般情况需要通过动态sql解决,但使用相同的unpivot。请查看bluefeet的answer here了解如何执行此操作。

您可以通过多种方式获取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工作,未分割的列的类型都需要相同。如果不是这样,请尝试通过NVARCHAR进行投射。
  • 如果您需要使用QUOTENAME,则需要在联接的两侧执行此操作。

答案 1 :(得分:0)

这没有意义!

您需要在单个值PK(主键)或多个值(复合键)上创建表A和B之间的关系。表1将具有PK到FK(外键)。

Column_A                Column_B 
---------------------------------------
Test A                  name
Test B                  address
Test C                  phone
Test D                  name


name        address         email       country         phone           
-------------------------------------------------------------------
Kush        KTM             a@a.c          NP           98545
Bush        BTM             b@b.d          NP           98545

当A和B都将名称作为值时,输出现在是什么?

你基本上违反了常态法则。

见下文,数据库通常是第3范式。

http://en.wikipedia.org/wiki/Database_normalization#Normal_forms

以下是一个更好的解决方案。

表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中的(值)相关。

http://en.wikipedia.org/wiki/Surrogate_key

还有其他方法可以做到这一点,但如果没有书面的业务规则,这是一种方式。

答案 2 :(得分:0)

您可以尝试动态sql,如:

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