SQL发送代码与另一个表匹配的值

时间:2016-02-02 20:42:34

标签: sql sql-server tsql ssis-2012

我有一张包含数据记录的表:

T1:

示例T1数据:

Unique_id   RatingA   RatingB   RatingC
    123       1          3       Null
    456      -1        Null       2

我有另一个表格,其代码等同于评分,

T2:

 Rating_Name  Rating_Code
   RatingA        11
   RatingB        21
   RatingC        31

我需要发送来自Unique_id的{​​{1}}来自T1的评分代码,评分值来自T2

期望的输出

我的导出文件应该如下所示,从相应的列(A,B或C)中取 Rating

T1

我该怎么做?

2 个答案:

答案 0 :(得分:2)

您可以使用CASE WHEN条款取消 ratingA,B C 的三个列:

SELECT      T1.Unique_id,
            T2.Rating_Code,
            CASE Rating_Name
                WHEN 'RatingA' THEN T1.RatingA
                WHEN 'RatingB' THEN T1.RatingB
                WHEN 'RatingC' THEN T1.RatingC
            END AS Rating
FROM        T1
CROSS JOIN  T2

输出:

+-----------+-------------+--------+
| Unique_id | Rating_Code | Rating |
+-----------+-------------+--------+
|    123    |       11    |    1   |
|    123    |       21    |    3   |
|    123    |       31    | (null) |
|    456    |       11    |   -1   |
|    456    |       21    | (null) |
|    456    |       31    |    2   |
+-----------+-------------+--------+

SQL Fiddle

如果您在 T2 中有其他记录而不是问题中给出的三个记录,那么请在声明的末尾添加WHERE子句:

WHERE       Rating_Name IN ('RatingA', 'RatingB', 'RatingC');

附录

正如您所说,实际上有许多(数百个)此类RatingXXX列,必须说这是一个糟糕的数据库设计。实际上,您要生成的输出应该是一个适当的表,您可以保持更新而不是这些列。

无论如何,为了帮助您生成上述SQL而无需键入数百个列名,您可以使用:

SELECT      concat('WHEN ''', Rating_Name, ''' THEN T1.', Rating_Name)
FROM        T2

这会输出类似:

WHEN 'RatingA' THEN T1.RatingA
WHEN 'RatingB' THEN T1.RatingB
WHEN 'RatingC' THEN T1.RatingC

...您可以将其复制到最终的SQL CASE子句中。这假设您的表 T2 中的评级名称是 T1 中的确切列名称。

答案 1 :(得分:0)

select Unique_id, Rating_Code, Rating
from
    T1 cross apply
    (values
        ('RatingA', RatingA),
        ('RatingB', RatingB),
        ('RatingC', RatingC)
    ) pvt(Rating_Name, Rating)
    inner join T2
        on T2.Rating_Name = pvt.Rating_Name

这与@ trincot的答案非常相似。一个小的不同之处是我假设你想要T2的所有值 no 。目前尚不清楚这是正确的还是将来可能不正确。在@ trincot的支持下,尽管不太可能,您的SQL Server版本上没有cross apply可用。