我有一个MSSQL 2012表格,其中只有某个工作表名称列的第一行包含客户,项目和的值工厂,基于ID。
现在我想“复制”这三列的记录到所有其他行,其中ID相同且sheetname =“sheet 1”。
这是一个带有输入和所需输出表的fiddle。
使用“copy”我的意思是我不想更新实际的表,而是想创建一个只有填充包含这些记录的列的视图。
目前我不知道如何到达那里,所以希望你可以帮助我。 我怀疑我的观点是否表现出色。我猜一个程序会做得更好。
谢谢。
更新 我已经用另一个任务更新了小提琴:我添加了一个注释列,如果记录为null,则应该使用先前的注释值。
答案 0 :(得分:1)
首先,你确实为输入表中的所有行添加了相同的id,我认为这是一个错误。然后我承认我没有完全得到你的解释,我认为你主要是因为一个糟糕的设计,没有主键,只有一个表,当你可以轻松地将你的表分成两个不同的表。 但是有一个简单的解决方案,再次不确定它真的能做你想要的,但他可以帮助你做到这一点。
SELECT
myInputTable.id,
myInputTable.row,
j.customer,j.project,
j.plant,myInputTable.sheetname
FROM myInputTable
LEFT JOIN myInputTable AS j
ON (myInputTable.id=j.id AND j.customer IS NOT NULL)
Join允许您在表格的结果中添加列 使用左连接,myInputTable的每一行至少有一行, 在on之后的条件,你说你只想在id是相同的并且如果有客户名称时添加一行j。
答案 1 :(得分:0)
您的设计存在缺陷。查看大量空值并将这些值标准化。经过另一次快速查看后,客户,项目和工厂可以标准化为其他表格 - 将这些表格连接在一起将为您提供输出2.
答案 2 :(得分:0)
如果所有其他列始终为null,则可以使用此视图,并且性能良好:
CREATE VIEW v_yourview as
SELECT id, row, min(customer) over (partition by id) customer,
min(project) over (partition by id) project,
min(plant) over (partition by id) plant,
sheetname
from myInputTable
如果要更新所有行。由于数据中没有时间戳或唯一ID,我通过添加临时row_number伪造它: (我相信你在你的小提琴中犯了一个错误,我试图纠正它)
CREATE TABLE #myInputTable
(
id int,
row int,
customer varchar(30),
project varchar(30),
plant varchar(30),
sheetname varchar(30),
comment varchar(30)
);
INSERT INTO #myInputTable
(id, row, customer,project,plant, sheetname,comment)
VALUES
(1,1, 'Customer Name', 'Project Name', 'Plant Name', 'sheet 1','comment 1')
,
(1,1,NULL ,NULL ,NULL , 'sheet 2',Null)
,(1,1,NULL ,NULL ,NULL , 'sheet 3',Null)
,(1,2,NULL ,NULL ,NULL , 'sheet 2','comment 2')
,(1,2,NULL ,NULL ,NULL , 'sheet 3',Null)
-- I changed value for ID from 1 to 2 in next line
,(2,1, 'Customer Name 2', 'Project Name', 'Plant Name', 'sheet 1', 'new comment')
,
(2,1,NULL ,NULL ,NULL , 'sheet 2',Null)
,(2,1,NULL ,NULL ,NULL , 'sheet 3',Null)
,(2,2,NULL ,NULL ,NULL , 'sheet 2',Null)
,(2,2,NULL ,NULL ,NULL , 'sheet 3',Null)
;with t1 as
(
select *, row_number() over (order by id) rn
from #myInputTable
)
update t1
set
customer = t2.customer,
project = t2.project,
plant = t2.plant,
comment = t3.comment
from t1
join #myInputTable t2
on t2.customer is not null
and t1.id = t2.id
cross apply(select top 1 comment from t1 t where rn <= t1.rn and comment is not null order by rn desc) t3
where t1.customer is null
select * from #myInputTable