Column values acquired in the first non-null value

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
Source Code

 

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;
Source Code

 

另一列[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;
Source Code

 

以上加个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;
Source Code

 

使用色彩来引示可以看到明白:

 

把以上方法去解决网友的问题,却得到另外一个结果:

 

对比一下,原来空值也应该有,就是当一个值都没有时,才用空值填充。

看来得改写一下程序,创建临时表,存储结果。

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
Source Code

 

Guess you like

Origin www.cnblogs.com/insus/p/10934929.html