连接列

时间:2019-07-18 13:52:14

标签: sql

我有2张桌子。

工作中心:

WC #  Activity1  activity2  activity3  activity4  
1     Labor      Run       Setup        Helper  
2      Setup      Helper    Labor           
3      Helper     Run  

活动:

WC #    Time1 Time2 Time3 Time4
1        1     2    3        4  
2        12    13   14  
3        21    22  

我的最终结果将是:

Wc#     Labortime Runtime Setuptime helpertime  
1         1         2      3           4  
2        14        13     12  
3        0         22      0           21  

如何实现?

3 个答案:

答案 0 :(得分:0)

您可以在下面的脚本中进行检查。虽然在输出和您的预期输出之间存在一些不匹配,但我认为在给定的数据中存在一些错误的预期输出。

SELECT A.[WC #],
ISNULL(
CASE 
    WHEN  Activity1 = 'Labor' THEN Time1 
    WHEN  Activity2 = 'Labor' THEN Time2
    WHEN  Activity3 = 'Labor' THEN Time3
    WHEN  Activity4 = 'Labor' THEN Time4
    ELSE NULL
END,0) Labortime,
ISNULL(
CASE 
    WHEN  Activity1 = 'Run' THEN Time1 
    WHEN  Activity2 = 'Run' THEN Time2
    WHEN  Activity3 = 'Run' THEN Time3
    WHEN  Activity4 = 'Run' THEN Time4
    ELSE NULL
END,0) Runtime,
ISNULL(
CASE 
    WHEN  Activity1 = 'Setup' THEN Time1 
    WHEN  Activity2 = 'Setup' THEN Time2
    WHEN  Activity3 = 'Setup' THEN Time3
    WHEN  Activity4 = 'Setup' THEN Time4
    ELSE NULL
END,0) Setuptime,
ISNULL(
CASE 
    WHEN  Activity1 = 'Helper' THEN Time1 
    WHEN  Activity2 = 'Helper' THEN Time2
    WHEN  Activity3 = 'Helper' THEN Time3
    WHEN  Activity4 = 'Helper' THEN Time4
    ELSE NULL
END,0) helpertime
FROM Workcenter A
INNER JOIN Actvity B ON A.[WC #] = B.[WC #]

答案 1 :(得分:0)

我找到的解决方案,我确定最好的方法不是UNPIVOT您的两个表(在2 CTEs中),然后根据您的[WC #]和列号(名称)(如您所见,在UNPIVOT查询中,我在列名的开头添加了一个数字,以确保我获得每个活动的正确时间)。 将所有内容保存在临时表中,并使用PIVOT作为最终结果。

declare @workcenter as table (
    wc int
    ,activity1 varchar(10)
    ,activity2 varchar(10)
    ,activity3 varchar(10)
    ,activity4 varchar(10)
);

insert into @workcenter values
(1, 'Labour', 'Run', 'Setup', 'Helper')
,(2, 'Setup', 'Helper', 'Labour', NULL)
,(3, 'Helper', 'Run', NULL, NULL)



declare @activity as table (
    wc int
    ,time1 int
    ,time2 int
    ,time3 int
    ,time4 int
);


insert into @activity values
(1, 1, 2, 3, 4)
,(2, 12, 13, 14, NULL)
,(3, 21, 22, NULL, NULL)



;with cte_wc as (
    select
        wc
        ,cast(ROW_NUMBER() OVER (Order by wc) as varchar)+ name as name
        ,value
    from @workcenter
    unpivot
    (
      value
      for name in (activity1, activity2, activity3,activity4)
    ) unpiv
)
, cte_a as (
    select
        wc
        ,cast(ROW_NUMBER() OVER (Order by wc) as varchar)+ name as name
        ,value
    from @activity
    unpivot
    (
      value
      for name in (time1, time2, time3,time4)
    ) unpiv
)

select distinct
    cte_wc.wc
    ,cte_wc.value as activity
    ,cte_a.value as time
into #tbl
from cte_wc
inner join cte_a
    on cte_wc.wc = cte_a.wc
    and LEFT(cte_wc.name, 1) = LEFT(cte_a.name, 1);



select *
from 
(
  select wc, activity, time
  from #tbl
) src
pivot
(
  max(time)
  for activity in ([Labour], [Run], [Setup], [Helper])
) piv;



drop table #tbl;

答案 2 :(得分:0)

如果可能的话,我强烈建议您更改数据库结构。就目前而言,您的结构并不理想:如果工作中心需要进行第五项活动,则必须对表进行结构更改,这是不理想的。另外,从其他2个答案可以证明,您的查询将很复杂。

我认为一个更好的设计是拥有一个包含以下属性的表:

  • work_center_id(可能是工作中心表的外键)
  • activity_name(或activity_name_id),它可能是可能活动表的外键
  • activity_time(可能是activity_time_seconds,以澄清其测量内容)。

此表中显示的数据如下所示:

+----------------+---------------+---------------+
| work_center_id | activity_name | activity_time |
+----------------+---------------+---------------+
|              1 | Labor         |             1 |
|              1 | Run           |             2 |
|              1 | Setup         |             3 |
|              1 | Helper        |             4 |
|              2 | Setup         |            12 |
|              2 | Helper        |            13 |
|              2 | Labor         |            14 |
|              3 | Helper        |            21 |
|              3 | Run           |            22 |
+----------------+---------------+---------------+

然后,要获取所需的数据,您可以使用基本的数据透视查询,例如使用如下所示的条件聚合:

SELECT
    work_center_id,
    SUM(CASE WHEN activity_name = 'Labor'   THEN activity_time ELSE 0 END) AS Labortime,
    SUM(CASE WHEN activity_name = 'Run'     THEN activity_time ELSE 0 END) AS Runtime,
    SUM(CASE WHEN activity_name = 'Setup'   THEN activity_time ELSE 0 END) AS Setuptime,
    SUM(CASE WHEN activity_name = 'Helper'  THEN activity_time ELSE 0 END) AS Helpertime
FROM activity_times
GROUP BY work_center_id