更新SQL Server 2008中源表中多个匹配行的查询?

时间:2013-10-02 16:54:25

标签: sql sql-server database sql-server-2008

我有两个表 - table1和table2。两个表的当前条件如下:

表1:

id   type mon   tue   wed   thu   fri   sat   sun  
1    ets  NULL  NULL  NULL  NULL    NULL    NULL    NULL 
1    ets  NULL  NULL  NULL  NULL    NULL    NULL    NULL 
1    eta  NULL  NULL  NULL  NULL    NULL    NULL    NULL 
1    eta  NULL  NULL  NULL  NULL    NULL    NULL    NULL 
1    cl   NULL  NULL  NULL  NULL    NULL    NULL    NULL 
1    cl   NULL  NULL  NULL  NULL    NULL    NULL    NULL 
2    ets  NULL  NULL  NULL  NULL    NULL    NULL    NULL 
2    ets  NULL  NULL  NULL  NULL    NULL    NULL    NULL 
2    eta  NULL  NULL  NULL  NULL    NULL    NULL    NULL 
2    eta  NULL  NULL  NULL  NULL    NULL    NULL    NULL 
2    cl   NULL  NULL  NULL  NULL    NULL    NULL    NULL 
2    cl   NULL  NULL  NULL  NULL    NULL    NULL    NULL 

表2:

id  ets eta cl
1   mon tue wed
1   thu fri sat
1   sun mon tue
2   sat sun mon
2   fri sat sun

请注意,table2中列的名称是列' type'在表1中。 我想以这样的方式更新table1:列mon-sun获取表2中为各个'类型' (即ets,eta或cl)和table1.id应匹配table2.id。

我想要的结果表格如下所示:

id   type mon   tue   wed   thu   fri   sat   sun  
1    ets  1     NULL  NULL  1     NULL  NULL    1 
1    ets  1     NULL  NULL  1     NULL  NULL    1
1    eta  1     1     NULL  NULL  1     NULL    NULL 
1    eta  1     1     NULL  NULL  1     NULL    NULL
1    cl   NULL  1     1     NULL  NULL  1       NULL 
1    cl   NULL  1     1     NULL  NULL  1       NULL
2    ets  NULL  NULL  NULL  NULL  1     1       NULL 
2    ets  NULL  NULL  NULL  NULL  1     1       NULL 
2    eta  NULL  NULL  NULL  NULL  NULL  1       1 
2    eta  NULL  NULL  NULL  NULL  NULL  1       1 
2    cl   1     NULL  NULL  NULL  NULL  NULL    1 
2    cl   1     NULL  NULL  NULL  NULL  NULL    1  

我申请的UPDATE查询如下:

update a
set a.mon = case b.ets when 'mon' then '1' else '0' end,
a.tue = case b.ets when 'tue' then '1' else '0' end,
a.wed = case b.ets when 'wed' then '1' else '0' end,
a.thu = case b.ets when 'thu' then '1' else '0' end,
a.fri = case b.ets when 'fri' then '1' else '0' end,
a.sat = case b.ets when 'sat' then '1' else '0' end,
a.sun = case b.ets when 'sun' then '1' else '0' end
from table1 a, table2 b
where a.id = b.id and a.type = 'ets'

考虑首先更新table1.type = 'ets'的表格,以及同时与id2匹配的ets的各个值。

上述查询仅获取table2中的第一个匹配值,并更新table1中的值而不是其余值。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

你必须在更新前“转动”你的桌子:

with cte as (
    select
        t.id, c.type,
        max(case when c.value = 'mon' then 1 end) as mon,
        max(case when c.value = 'tue' then 1 end) as tue,
        max(case when c.value = 'wed' then 1 end) as wed,
        max(case when c.value = 'thu' then 1 end) as thu,
        max(case when c.value = 'fri' then 1 end) as fri,
        max(case when c.value = 'sat' then 1 end) as sat,
        max(case when c.value = 'sun' then 1 end) as sun
    from Table2 as t
        outer apply (values
            ('ets', t.[ets]),
            ('eta', t.[eta]),
            ('cl', t.[cl])
        ) as c(type, value)
    group by t.id, c.type
)
update Table1 set
    mon = c.mon,
    tue = c.tue,
    wed = c.wed,
    thu = c.thu,
    fri = c.fri,
    sat = c.sat,
    sun = c.sun
from Table1 as t
    inner join cte as c on c.id = t.id and c.type = t.type

<强> sql fiddle demo

另一种方法是使用pivot / unpivot:

with cte_up as (
    select id, 1 as value, type, name
    from Table2
    unpivot (name for type in ([ets],[eta],[cl])) as up
), cte_p as (
    select *
    from cte_up
    pivot (max(value) for name in ([mon], [tue], [wed], [thu], [fri], [sat], [sun])) as p
)
update Table1 set
    mon = c.mon,
    tue = c.tue,
    wed = c.wed,
    thu = c.thu,
    fri = c.fri,
    sat = c.sat,
    sun = c.sun
from Table1 as t
    inner join cte_p as c on c.id = t.id and c.type = t.type

<强> sql fiddle demo