我有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
如何实现?
答案 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