SQL kérdések - Szoftverfejlesztés fórum

üzenetek

hozzászólások


bambano
(titán)
Blog

nem kellene hisztiznie, hogy a select foszamla,alszamla részben a főszámla és az alszámla melyik táblából van?


nyunyu
(félisten)

De kéne.

Eredeti DBben nem ugyanúgy hívják a hiteligenylesek meg a másik rendszerből származó táblákban a számlaszámos mezőket, így nem akadt fenn azon az Oracle, hogy elfelejtettem táblaaliast írni a select oszlopai elé, mivel egyértelmű volt, hogy melyik táblából jön.

Csak itt a szemléltetés kedvéért olvashatóbbá egyszerűsítettem a kódot, és nem követtetem a DBnk örökölt hülyeségeit, hogy minden táblában másképp hívják ugyanazokat a mezőket, aszerint, hogy ki mikor/hogyan specifikálta. :W

Pl. createdate vs create_date még az egyszerűbbik eset...

[ Szerkesztve ]


nyunyu
(félisten)

Ehh, and t.torlesi_datum is not null helyett and t.torlesi_datum > h.letrehozasi_datum kellett volna, és akkor biztosan nem nyírom ki a rossz ideiglenes számlaszámon létrejött friss igényléseket.
(Véglegeset 1 munkanappal később kaptak volna a számlavezető rendszertől, ami biztosan különböző lett volna a korábbiaktól.)

Asszem felírhatom a kéménybe korommal, hogy ez az n+1-edik módszer, ahogy a rendszerünk képes elkefélni az adatokat.

[ Szerkesztve ]


bambano
(titán)
Blog

szóval az adatbáziskezelő megint az utasításaid szerint működött?
;]


nyunyu
(félisten)

Az a bajom, hogy túlzottan alulnézetből látom az adatokat, és nem mindig ismer(het)em a keletkezésük, elromlásuk pontos körülményeit a különböző rendszerek közti adatszinkronizációk útvesztőjében, viszont nekem kéne helyrekalapálni a félreálló biteket.

Bár elnézve azt,hogy ~3500 GDPR érett igénylést akartam javítani, de belekerült 10 friss is a szórásba, az csak 0.3% hibaarány, bőven elviselhető kerekítési hiba :DDD


tm5
(tag)

UPDATE/DELETE végrehajtása előtt nem szoktál egy
--UPDATE/DELETE
SELECT * FROM
és a query többi része
lekérdezést futtatni? Nekem néhányszor mentett már életet.


nyunyu
(félisten)

Alaposan le volt tesztelve a query, csak arra nem számítottam, hogy a tesztek után 2 héttel élesítéskor lesznek olyan igénylések, amik a különböző rendszereink közötti útvesztőben ideiglenesen hibás állapotban lesznek.
Tesztek idején még nem is léteztek!!!


cattus
(őstag)

Hali,

Az alábbi problémával szembesültem amit egyelőre nem sikerült megoldani. Postgres alatt adott két tábla, Users (id, customer_id) és Subscriptions (customer, status, created). Egy userhez nulla vagy több subscription is tartozhat (customer - customer_id kapcsolat). Az lenne a célom, hogy minden userhez lekérjem a legfrissebb subscription statuszát (created alapján, ha nincs, akkor null). Mi lenne erre a legegyszerűbb megoldás?


nyunyu
(félisten)

select u.*, s.status
from users u
left join (
select x.*,
row_number() over (partition by customer_id order by created desc) rn
from subscription x
) s
on s.customer_id = u.customer_id
and s.rn = 1;

Beszámozod a subscription táblát ügyfelenkénti létrehozási dátum szerint csökkenőbe, aztán ebből joinolod az első rekordot az usershez.

(Nem szeretek alquerykben group by-jal bohóckodni, mert úgy sokkal hosszabb+bonyolultabb+olvashatatlanabb lenne a kód.)

[ Szerkesztve ]


nyunyu
(félisten)

Mármint sokkal egyszerűbb, mint ügyfelenként meghatározni az utolsó előfizetési dátumot, és az ahhoz tartozó rekordot visszakeresni az előfizetés táblában, hogy utána joinolhassam az előfizetőhöz:

select u.*, s.status
from users u
left join (
select *
from subscription
where (customer_id, createdate) in (
select customer_id, max(createdate)
from subscription
group by customer_id) s
on s.customer_id = u.customer_id;

(Tényleg, Oraclen kívül van más olyan DB is, ami támogatja a sokoszlopos IN / NOT IN műveleteket?
Ha jól rémlik, ez a szintaxis nincs szabványosítva)

Valószínűleg ablakozós max() függvénnyel is lehetne írni, és akkor nem kellene a group by köré írt külső query:
select u.*, s.status
from users u
left join (
select *
from subscription
where createdate = max(createdate) over (partition by customer_id)
) s
on s.customer_id = u.customer_id;

Talán így a legrövidebb a kód.

[ Szerkesztve ]


nyunyu
(félisten)

Szerkesztési idő lejárt. :(

Ha az ügyfélnek két azonos időbélyegű előfizetése van, akkor a row_number() -es megoldás véletlenszerűen vagy az egyiket vagy a másik státuszát fogja visszaadni, így csak 1 sor fog hozzá tartozni.
Míg a másik két opció mindkét legfrissebb előfizetés státuszát visszaadja, azokkal egy ügyfélhez 2 sort fogsz kapni.

(Ha a row_number()-t rank()-ra cseréled, akkor az is mindkettőt vissza fogja adni.)


cattus
(őstag)

Köszi a részletes választ, egy időben egy userhez csak egy előfizetés tartozik, így az első is szuperül működik.

üzenetek