The title of the conformity with the purpose of users, in addition to the discussion, so for the time being. Like a proper solution of the problem, we will have to see the original discussion topic.
This is an online problem as follows,
;with temp as ( select '63738893' repair_no,'20190504' report_date,'HES2418819040700003'service_sheet_no,null sno,'467769309410' rno union all select '63738893' repair_no,'20190504' report_date,'HES2418819040700003'service_sheet_no,'467769309411' sno,null rno union All SELECT ' 63,738,793 ' repair_no, ' 20,190,508 ' REPORT_DATE, ' HES2418819040700003 ' service_sheet_no, ' 467 769 309 411 ' SnO, null RNO ) SELECT * from TEMP - more original data - Results less desired ; with TEMP AS ( SELECT ' 63,738,893 ' repair_no, ' 20,190,504 ' REPORT_DATE, ' HES2418819040700003 'service_sheet_no,'467769309411' sno,'467769309410' rno union all --select '63738893' repair_no,'20190504' report_date,'HES2418819040700003'service_sheet_no,'467769309411' sno,null rno union all select '63738793' repair_no,'20190508' report_date,'HES2418819040700003'service_sheet_no,'467769309411' sno,null rno )select * from temp
Here is Insus.NET implementation. Another create a temporary table, add a field ID than the users of the data table, delete some unrelated to the question of the field.
Implemented in MS SQL Server 2017 version.
Insus.NET approach is to use ROW_NUMBER and PARTITION when the line grouping:
The first analysis of a [sno], take a look:
;WITH s AS ( SELECT ROW_NUMBER() OVER(PARTITION BY [repair_no] ORDER BY [id],[sno]) AS [ROW_NUM], [id], [repair_no], [sno] FROM #T WHERE [sno] IS NOT NULL ) SELECT [ROW_NUM],[id],[repair_no],[sno] FROM s;
另一列[rno]:
;WITH r AS ( SELECT ROW_NUMBER() OVER(PARTITION BY [repair_no] ORDER BY [id],[rno]) AS [ROW_NUM], [id], [repair_no], [rno] FROM #T WHERE [rno] IS NOT NULL ) SELECT [ROW_NUM],[id],[repair_no],[rno] FROM r;
以上加个ID列,主要是为了让大家看到它的排序,拿到的是第一列非空的值。网友的问题,直接按[repair_no]排序即可。
下面代码是把上面2列合并在一起。
;WITH s AS ( SELECT ROW_NUMBER() OVER(PARTITION BY [repair_no] ORDER BY [id],[sno]) AS [ROW_NUM], [id], [repair_no], [sno] FROM #T WHERE [sno] IS NOT NULL ), r AS ( SELECT ROW_NUMBER() OVER(PARTITION BY [repair_no] ORDER BY [id],[rno]) AS [ROW_NUM], [id], [repair_no], [rno] FROM #T WHERE [rno] IS NOT NULL ) SELECT s.[repair_no],[sno],[rno] FROM s INNER JOIN r on (s.[repair_no] = r.[repair_no]) WHERE s.[ROW_NUM] = 1 AND r.ROW_NUM = 1;
使用色彩来引示可以看到明白:
把以上方法去解决网友的问题,却得到另外一个结果:
对比一下,原来空值也应该有,就是当一个值都没有时,才用空值填充。
看来得改写一下程序,创建临时表,存储结果。
2个字段分别处理,把结果MERGE来合并至临时表中:
CREATE TABLE #ok_result([repair_no] INT,[sno] nvarchar(50),[rno] NVARCHAR(50)) ;with temp as ( select '63738893' repair_no,'20190504' report_date,'HES2418819040700003'service_sheet_no,null sno,'467769309410' rno union all select '63738893' repair_no,'20190504' report_date,'HES2418819040700003'service_sheet_no,'467769309411' sno,null rno union all select '63738793' repair_no,'20190508' report_date,'HES2418819040700003'service_sheet_no,'467769309411' sno,null rno ),s AS ( SELECT ROW_NUMBER() OVER(PARTITION BY [repair_no] ORDER BY repair_no) AS [ROW_NUM], [repair_no], [sno] FROM temp WHERE [sno] IS NOT NULL ) MERGE #ok_result AS Target USING (SELECT [repair_no],[sno] FROM s WHERE [ROW_NUM] = 1) AS Source ON (Target.[repair_no] = Source.[repair_no]) WHEN MATCHED THEN UPDATE SET target.[sno] = source.[sno] WHEN NOT MATCHED BY TARGET THEN INSERT ([repair_no],[sno]) VALUES ([repair_no],[sno]); ;with temp as ( select '63738893' repair_no,'20190504' report_date,'HES2418819040700003'service_sheet_no,null sno,'467769309410' rno union all select '63738893' repair_no,'20190504' report_date,'HES2418819040700003'service_sheet_no,'467769309411' sno,null rno union all select '63738793' repair_no,'20190508' report_date,'HES2418819040700003'service_sheet_no,'467769309411' sno,null rno ),r AS ( SELECT ROW_NUMBER() OVER(PARTITION BY [repair_no] ORDER BY repair_no) AS [ROW_NUM], [repair_no], [rno] FROM temp WHERE [rno] IS NOT NULL ) MERGE #ok_result AS Target USING (SELECT [repair_no],[rno] FROM r WHERE [ROW_NUM] = 1) AS Source ON (Target.[repair_no] = Source.[repair_no]) WHEN MATCHED THEN UPDATE SET target.[rno] = source.[rno] WHEN NOT MATCHED BY TARGET THEN INSERT ([repair_no],[sno]) VALUES ([repair_no],[rno]); SELECT [repair_no],[sno],[rno] FROM #ok_result