基于列名的sql更新

前端之家收集整理的这篇文章主要介绍了基于列名的sql更新前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有个问题.

我有T1,T2,T_Join表.

T_Join:第一列:ID(唯一)例如:10,11,12,13.第二列:CODE,它包含的属性等于T2的列名.例如:类型,来源,部分,重要性.这些由T1中的ID标识.据此,属性’source’的ID是11.

ID  CODE
10  type
11  source
12  section
13  importance

在表T1中,第一列是不唯一的data_ID:1020,1020,1022,1023,1028,1035,1035等.

第二列是来自T_Join的ID.在此示例中,4 ID可以属于1 data_ID,这些声明的值出现在第三列(VALUE)中:

data_ID  ID  VALUE  
1020     10  1
1020     11  123
1020     12  9
1020     13  4
1022     10  2
1022     12  15
1023     10  2
1023     11  108
1023     13  2
1028     12  20

这意味着具有ID 1020的项目是类型1,源自源No.123,该实际对象由存储在第9节中的该ID识别并具有第四级重要性.

现在,我有一张桌子T2.第一列与T1中的data_ID相同.在这张表中,这些是独特的.其他栏目:(多么令人惊讶!)类型,重要性. (实际上,不仅有四个属性,而且至少有五十个!)
所以表看起来像这样:

data_ID  type  source  section  importance
1020     1     123     9        2
1022     1     95      3        5
1023     2     108     21       4
1028     1     147     17       5

T2包含较新的数据.我想用这些更新T1.VALUE列.按照上面的示例,更新的T1应如下所示:

data_ID  ID  VALUE  
1020     10  1
1020     11  123
1020     12  9
1020     13  2
1022     10  1
1022     12  3
1023     10  2
1023     11  108
1023     13  4
1028     12  17
...

因此,在data_ID 1020处,重要性为4并且它变为2,因为在T1中ID为13并且它从T_Join表引用属性“重要性”,依此类推.
我想以这种方式更新所有数据.我不是sql专家,我设法创建了这个代码

update T1 set VALUE = 
(select * from T2 
 inner join T_Join on ID=
(SELECT 
    c.name 
FROM
    sys.objects o
INNER JOIN
    sys.columns c
ON
    c.object_id = o.object_id
AND o.name = 'T2') 
where T1.data_ID = T2.data_ID and T2.ID = T_Join.ID)

from T1
inner join T2 on T1.data_ID = T2.data_ID
inner join T_Join on T1.ID = T_Join.ID

select * from T1

但它不起作用,错误信息:

Msg 116,Level 16,State 1,Line 16
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

我尝试使用CURSOR语句和声明的变量(基于建议)解决它,但它也不起作用.

如果有人知道如何解决这个问题(以最简单的方式),请尽可能详细地回答.

解决方法

您当前设计的问题是您有一个规范化的表和一个非规范化的表,您需要执行更新.

首先,您需要对T2表进行反规范化,这将采用列并将其转换为行.在sql Server 2005中,他们引入了UNPIVOT函数,它将为您执行此操作.

第一步是将T2和T_Join中的数据选择为行. SELECT语句是:

select j.id,j.code,u.data_id,u.value
from T_Join j
inner join
(
  select data_id,col,value
  from T2
  unpivot
  (
    value
    for col in (type,source,section,importance)
  ) unpiv
) u
  on j.code = u.col

请参阅SQL Fiddle with Demo.这将获取您的列数据并将其转换为给出结果的行:

| ID |       CODE | DATA_ID | VALUE |
-------------------------------------
| 10 |       type |    1020 |     1 |
| 11 |     source |    1020 |   123 |
| 12 |    section |    1020 |     9 |
| 13 | importance |    1020 |     2 |
| 10 |       type |    1022 |     1 |
| 11 |     source |    1022 |    95 |
| 12 |    section |    1022 |     3 |
| 13 | importance |    1022 |     5 |
| 10 |       type |    1023 |     2 |
| 11 |     source |    1023 |   108 |
| 12 |    section |    1023 |    21 |
| 13 | importance |    1023 |     4 |
| 10 |       type |    1028 |     1 |
| 11 |     source |    1028 |   147 |
| 12 |    section |    1028 |    17 |
| 13 | importance |    1028 |     5 |

一旦数据采用该格式,您就可以在UPDATE语句中使用它:

update t1
set t1.value = t.value
from t1
inner join
(
  select j.id,u.value
  from T_Join j
  inner join
  (
    select data_id,value
    from T2
    unpivot
    (
      value
      for col in (type,importance)
    ) unpiv
  ) u
    on j.code = u.col
) t
  on t1.data_id = t.data_id
  and t1.id = t.id;

SQL Fiddle with Demo.

您声明的下一个问题是您需要大约50个列才能取消.如果是这种情况,那么您可以使用动态sql获取要转换为行的列列表.您的动态sql脚本将是:

DECLARE @colsUnpivot AS NVARCHAR(MAX),@query  AS NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('T2') and
               C.name not in ('data_ID')
         for xml path('')),1,'')

set @query 
  = 'update t1
     set t1.value = t.value
     from t1
     inner join
     (
       select j.id,u.value
       from T_Join j
       inner join
       (
         select data_id,value
         from T2
         unpivot
         (
           value
           for col in ('+@colsUnpivot+')
         ) unpiv
       ) u
         on j.code = u.col
     ) t
       on t1.data_id = t.data_id
       and t1.id = t.id;'

exec(@query);

SQL Fiddle with Demo.

代码将使用以下结果更新T1:

| DATA_ID | ID | VALUE |
------------------------
|    1020 | 10 |     1 |
|    1020 | 11 |   123 |
|    1020 | 12 |     9 |
|    1020 | 13 |     2 |
|    1022 | 10 |     1 |
|    1022 | 12 |     3 |
|    1023 | 10 |     2 |
|    1023 | 11 |   108 |
|    1023 | 13 |     4 |
|    1028 | 12 |    17 |

猜你在找的MsSQL相关文章