채 null 마지막으로 null 이 아닌 값에 SQL 서버에 우편코드

0

질문

나는 두 개의 테이블 PostalCodes (하나의 열의 값으로 00-00 을 99-999)및 Customers (는 옆에 있는 모든 고객의 데이터,우편번호와 ID 의 직원은 고객 서비스).

그래서 이 두 나는 단순히 가을 통해 우편 번호:

SELECT DISTINCT
    KP.postal,
    K.IDemp
FROM
    PostalCodes KP 
LEFT JOIN
    [Customers] K ON K.postal = KP.postal

나이:

| postal | IDemp |
+--------+-------+
| 00-000 | NULL  |
| 00-001 | NULL  |
| 00-001 | 12PH  |
| 00-002 | NULL  |
| 00-003 | NULL  |
| 00-004 | NULL  |
| 00-004 | 10PH  |
| 00-005 | NULL  |
| ...    | ...   |

그래서 당신이 볼 수 있듯이 모든 우편코드에서 사용되는 Customers 테이블,나만을 위한 목표가 모두 필요 우편 번호가 할당된 일부 직원에게 무언가를 만들었음의 영역"서비스",그래서 그렇게 하기 위해서 내가 채우려는 null 값을 마지막으로 null 이 아닌 값을 뭔가를 얻기 위해 다음과 같다:

| postal | IDemp |
+--------+-------+
| 00-000 | NULL  |
| 00-001 | 12PH  |
| 00-002 | 12PH  |
| 00-003 | 12PH  |
| 00-004 | 10PH  |
| 00-005 | 10PH  |
| ...    | ...   |

LAG() 기능,그러나 그것은 작동하지 않는(또는 적어도 내가 알지 못하는 방법을 제대로 사용)

LAG(K.IDemp) OVER (ORDER BY KP.postal)

내가 찾은 몇 가지 질문과 비슷한 이미할 수 있지만 오지 않을 사용하는 방법들에 대한 답변을 경우입니다.

sql sql-server
2021-11-23 13:11:15
2

최고의 응답

2

SQL 서버가 지원하지 않는 무시 null 에서 옵션을 LAG (아직),하지만 당신은 주위에 얻을 수 있습니다 이것을 만들어 바이너리 값이 열에서 당신이 원하는 순서에 의해,그리고 열 당신이 검색하고 전화 MAX 는 무시 null. 전체 작업 솔루션이 될 것이다:

IF OBJECT_ID(N'tempdb..#T', 'U') IS NOT NULL
    DROP TABLE #T;

CREATE TABLE IF NOT EXISTS #T (Postal VARCHAR(6) NOT NULL, IDemp VARCHAR(4) NULL);
INSERT #T (Postal, IDemp)
VALUES
    ('00-000', NULL),
    ('00-001', '12PH'),
    ('00-002', NULL),
    ('00-003', NULL),
    ('00-004', '10PH'),
    ('00-005', NULL);


SELECT  *,
        LastNonNull = CONVERT(VARCHAR(6), 
                            SUBSTRING(
                                MAX(CONVERT(BINARY(6), Postal) + CONVERT(BINARY(4), IDemp)) 
                                    OVER(ORDER BY Postal), 7,4))
FROM    #T;

그것은 도움이 될 수 있는지 설명하는 경우 이것은 깨진 비트와 우리의 결과에 이:

SELECT  *,
        BinaryValue = CONVERT(BINARY(6), Postal) + CONVERT(BINARY(4), IDemp)
FROM    #T
IDemp BinaryValue
00-000 NULL NULL
00-001 12PH 0x30302D30303131325048
00-002 NULL NULL
00-003 NULL NULL
00-004 10PH 0x30302D30303431305048
00-005 NULL NULL

이후 연결하는 null 값을 얻을 수 null 값을,당신은 단지 당신의 값을 곳 그렇지 않은 null 입니다. 할 수 있습니다 다음의 활용 바이너리 정렬(왼쪽에서 오른쪽)이고 최대값이 바이너리에서 윈도우 기능,일부입니다: MAX(...) OVER(ORDER BY Postal).

이 모두 제거합 NULL 값은(이후 MAX 를 무시 NULL는)외에도에서 첫 번째 행에 없기 때문에 이전의 비 null 값을 제공 데이터에 다음과 같다:

IDemp MaxBinaryValue
00-000 NULL NULL
00-001 12PH 0x30302D30303131325048
00-002 NULL 0x30302D30303131325048
00-003 NULL 0x30302D30303131325048
00-004 10PH 0x30302D30303431305048
00-005 NULL 0x30302D30303431305048

그런 다음 경우의 추출의 부분을 바이너리에 관심이 있다(자 7-10)및 변환을 다시 varchar 사용 SUBSTRINGCONVERT

2021-11-23 13:48:50
1

상호 연관된 하위 쿼리도 작동:

SELECT DISTINCT
    KP.postal,
    (SELECT TOP 1 K.IDemp 
     FROM [Customers] K
     WHERE K.postal <= KP.postal
     AND K.IDemp Is Not Null
     ORDER BY K.postal DESC) As IDemp
FROM
    PostalCodes KP 
2021-11-23 13:38:05

나는 이와 유사한 것을 제안은 위의 그러나 십자가 적용은 다음 빠릅니다. 수은 경우 null 을 처음은 null 입니다. 그래서 찾아야에서 양 방향으로 정렬하여 차등 대 우편
vikjon0

나는 그것에 따라 달라는 인덱스는데,기대 상관된 하위 질 CROSS APPLY 을 생산하는 매우 유사한 계획이다.
Richard Deeming

가능하게,내가 나쁜 경험이 있었는 과거에 하지만 물론 SQL server 진화했다. 가 있었을 때 시간이 다시 쓰기 오래된 중첩된 코드를 십자가에 적용되었는 확실한 성공을 하지만 물론 이 경우에는 일을 잘 못했을 볼 수 있습니다.
vikjon0

추가 AND K.IDemp IS NOT NULL 를 하위에 주문을 무시하 null.
Thorsten Kettner

@ThorstenKettner 그것에서 분명하지 않지만,나는 가정 IDempCustomers 테이블 NOT NULL.
Richard Deeming

보 결과의 협동의 쿼리가 있습니다. 우편 번호 00-001 결과를 두 행에,하나 IDemp'12PH'하나 IDemp NULL 입니다. 그래서 NULL 할 수 없는 줄기에서 외부에 가입하지만 존재해야 합니다 고객 테이블에서.
Thorsten Kettner

@ThorstenKettner 좋은 잡을 수 있습니다.
Richard Deeming

다른 언어로

이 페이지는 다른 언어로되어 있습니다

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................