Náplň nepovoľuje hodnoty null s posledným not null hodnotu v SQL Server Psč

0

Otázka

Mám dve tabuľky PostalCodes (jeden stĺpec s hodnotami z 00-00 na 99-999) a Customers (čo má, vedľa všetky zákazníka údajov, poštové smerovacie číslo a ID zamestnanca, ktorý slúži na zákazníka).

Takže tieto dva som jednoducho spájajúcej cez psč:

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

a vypisuje toto:

| 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  |
| ...    | ...   |

Takže ako vidíte, nie všetky poštové kódy sa používajú v Customers tabuľky, ale pre môj cieľ potrebujem všetky poštové kódy priradené niektoré zamestnanca, ktorý ho vytvoril niečo ako "oblasti služieb", tak k tomu, že som chcete vyplniť hodnoty null s posledným not null hodnotu dostať niečo ako toto:

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

Snažil som sa používať LAG() funkcia, ale to nefunguje (alebo aspoň ja neviem, ako ho používať správne)

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

Našiel som pár podobné otázky už teraz, ale nemohol prísť, ako využiť svoje odpovede na môj prípad.

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

Najlepšiu odpoveď

2

SQL Server nepodporuje ignorovať nepovoľuje hodnoty null možnosť na LAG (zatiaľ), ale môžete obísť vytvorením binárnu hodnotu zo stĺpca, podľa ktorého chcete objednávku, a na stĺpec, ktorý chcete vybrať, a telefonovanie MAX čo sa ignorovať nepovoľuje hodnoty null. Celý pracovný riešením by bolo:

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;

Môže to pomôcť, vysvetliť, ak je to v členení trochu pozrieme na výsledky:

SELECT  *,
        BinaryValue = CONVERT(BINARY(6), Postal) + CONVERT(BINARY(4), IDemp)
FROM    #T
Poštová 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

Od zreťazením null hodnotu, výnosy hodnotu null, dostanete len hodnoty, ak nie je null. Potom môžete využiť binárne triedenie (zľava doprava) a získať maximálnu hodnotu tento binárny v oknami funkciu, ktorá je súčasťou: MAX(...) OVER(ORDER BY Postal).

Tým sa odstráni všetky hodnoty NULL (od MAX ignoruje NULL) na rozdiel od prvého riadku, pretože nie je tam žiadny predchádzajúci non null hodnotu a poskytuje údaje takto:

Poštová 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

To je potom len prípade extrakcie časť binárne vás zaujíma (znaky 7-10) a prevod späť na varchar pomocou SUBSTRING a CONVERT

2021-11-23 13:48:50
1

Súvzťažnej sub-dopyt môže pracovať:

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

Myslím, že to je podobné tomu, čo navrhujem, je uvedené vyššie, ale kríž uplatňujú sa potom rýchlejšie. Mohla byť null, ak prvý z nich je nulová. Tak by mal vyzerať v oboch smeroch a triediť podľa diff na cieľové poštové
vikjon0

Myslím, že to bude závisieť na indexy, ale ja by som očakávať, že koreluje sub-dotaz a CROSS APPLY na výrobu veľmi podobné plány.
Richard Deeming

Možno som mal zlé skúsenosti v minulosti, ale samozrejme SQL server vyvinula . Tam bol čas, keď sa znovu písať staré vnorené kód kríž uplatňujú bol istý úspech, ale samozrejme prípadov, ktoré pracovali v poriadku, nikdy by som už videl.
vikjon0

Pridať AND K.IDemp IS NOT NULL ak poddotaz s cieľom zanedbávanie nepovoľuje hodnoty null.
Thorsten Kettner

@ThorstenKettner To nie je jasné z otázku, ale ja by som predpokladať, že IDemp stĺpec v Customers tabuľka NOT NULL.
Richard Deeming

Pozrite sa na výsledok z OP je dopyt. Psč 00-001 výsledky v dvoch radov, jeden s IDemp '12PH" jeden s IDemp NULL. Takže NULL nemôže pochádzať z vonkajšie, ale musia existovať v tabuľke zákazníci.
Thorsten Kettner

@ThorstenKettner Dobrý úlovok.
Richard Deeming

V iných jazykoch

Táto stránka je v iných jazykoch

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