열 값은 제 널이 아닌 값을 취득

다음은 토론에 추가하여 사용자의 목적과 적합성의 제목, 그래서 시간이되고. 문제의 적절한 해결책처럼, 우리는 원래의 토론 주제를 참조해야합니다.

이것은 다음과 같이 온라인 문제

;  임시   
( 
    선택  ' 63738893 ' repair_no, ' 20190504 ' REPORT_DATE, ' HES2418819040700003 ' service_sheet_no이 널 (null) SNO, ' 467769309410 ' RNO의 조합이  모두 
    선택  ' 63738893 ' , repair_no를 ' 20190504 ' REPORT_DATE, ' HES2418819040700003 ' service_sheet_no, ' 467769309411 ' SNO, 모든 
    SELECT  ' 63738793 ' repair_no, ' 20190508 ' REPORT_DATE, ' HES2418819040700003 ' service_sheet_no, ' 467 769 309 411 ' 산화 주석, RNO 
) SELECT  *  에서  TEMP 
- 더 오리지널 데이터 
- 덜 원하는 결과 
;  TEMP  AS  
( 
    SELECT  ' 63738893을 ' repair_no, ' 20190504 ' REPORT_DATE, ' HES2418819040700003 'service_sheet_no, ' 467769309411 ' SNO는 ' 467769309410 ' RNO의 조합은  모든 
    - '63738893'repair_no, '20190504'REPORT_DATE, 'HES2418819040700003'service_sheet_no,'467769309411 'SNO, 널 RNO 조합 모두 선택 
    을 선택  ' 63738793 ' repair_no, ' 20190508 ' REPORT_DATE을 , ' HES2418819040700003 ' service_sheet_no, ' 467769309411 ' SNO, RNO 
) 선택  *  로부터  임시
소스 코드

 

여기 Insus.NET 구현입니다. 또, 데이터 테이블의 사용자보다 필드 ID를 추가 필드의 질문에 어떤 관련이없는 삭제, 임시 테이블을 만들 수 있습니다.

MS SQL 서버 2017 버전에서 구현됩니다.

 

Insus.NET 접근 방식이 사용하는 것입니다 ROW_NUMBER파티션을 할 때 라인 그룹 :

A [SNO]의 첫 번째 분석은 살펴 :

 

;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

 

추천

출처www.cnblogs.com/insus/p/10934929.html