Xyloto pon 16.12.2019 16:44

Pozdrav, imam slijedeći problem:

 

U tablici transakcija imam slijedeće podatke:

 

ID_TRAN OBRACUN VRIJEME  DATUM     SIFRA

1       AB      08:15   2019-10-10  S001

2       BB      09:20   2019-10-11  S002

3       BC      10:20   2019-10-11  S002

4               11:12   2019-10-11  S002

 

u tablici periodi obračuna imam zapisan datum i vrijeme pojedinog obračuna

 

ID OBRACUN OD_VREMENA DO_VREMENA  DATUM      SIFRA

1   AB      06:50       08:30       2019-10-10  S001

2   BB      08:45       10:00       2019-10-11  S002

3   BC      10:01       11:10       2019-10-11  S002

4   CC      11:50       12:30       2019-10-11  S002

 

Trebam prema ovim podacima perioda obračuna definirati obračun za transakciju pod ID-jem 4 u prvoj tablici. 

U drugoj tablici nemam definiran period za vrijeme od 11:12 ali tu transakciju trebam svrstati u idući period 

koji je manji od vremene 11:12 (u odnosi na kolonu OD_VREMENA ona mi služi kao rubni uvjet),

što bi značilo da bi trebalo upasti u period BC 10:01 - 11:10.

 

Što bi značilo da transakcija pod ID 4 ide kao:

 

4      BC       11:12   2019-10-11

 

Edit: Zaboravio sam dodati kolonu šifra.

Xyloto pon 16.12.2019 21:29

Evo kako sam ja napisao ali i samom mi se ne sviđa kako je napisano :/

 


select
   t.Vrijeme, t.Sifra, t.Datum, o.Sifra, o.Obracun, o.DATUM, o.MIN_VRIJEME, o.MAX_VRIJEME,
   rub.Sifra, rub.Obracun, rub.DATUM, rub.MIN_VRIJEME, rub.MAX_VRIJEME
from dbo.Transakcija t
inner join dbo.Obracuni o on t.Sifra = o.Sifra and t.DATUM = o.DATUM
inner join
(
    select
     P1.Sifra, P1.OBRACUN, P1.DATUM, P1.MIN_VRIJEME, MAX_VRIJEME = P2.MIN_VRIJEME
    from
    (
     select
      SIFRA, OBRACUN, DATUM, MIN_VRIJEME, ROW_NUMBER() OVER(ORDER BY SIFRA, DATUM, OBRACUN) RNUM
     from dbo.Obracuni
    ) P1
    inner join
    (select
      SIFRA, OBRACUN, DATUM, MIN_VRIJEME, - 1 + ROW_NUMBER() OVER(ORDER BY SIFRA, DATUM, OBRACUN) RNUM
    from dbo.Obracuni
    ) P2 on P1.RNUM = P2.RNUM
) rub on o.SIFRA = rub.SIFRA and o.DATUM = rub.DATUM
where
(
  t.Vrijeme >= o.MIN_VRIJEME
  and
  t.Vrijeme <= o.MAX_VRIJEME
)
or
(
t.Vrijeme >= rub.MIN_VRIJEME
and
t.Vrijeme <= rub.MAX_VRIJEME
)

and rub.OBRACUN = o.OBRACUN

Bobobo-bo Bo-bobo sri 18.12.2019 16:20

Probaj s cross apply dohvatiti "najbolji" redak obračuna za svaku transakciju:

 

select t.*, o.*
from dbo.Transakcija t
cross apply (
  select top 1 obr.*
  from dbo.Obracuni obr
  where obr.SIFRA = t.SIFRA and obr.DATUM = t.DATUM and obr.MIN_VRIJEME <= t.VRIJEME
  order by obr.MIN_VRIJEME desc
) o

ihush sri 18.12.2019 20:29

--ako nisi razumio gornju poruku.. svaki uvjet koji postaviš za if < ili <= .. koji zadovolji kriterij vrijeme od/do je 'točan' dok trebaš pronaći najbliže vrijeme, tj posljednje/predposljednje koje zadovoljava raspon od-do kriterija.

 

tj imaš logično formalnu grešku, 'izmišljanje' podatka koji ti nedostaje ili pogađanje. Prvo, to ako je moguće ne smije ni biti, kod unosa podatka unos vremena ili iz tekućeg.. a tad nema ni pogađanja.

-ako je već tako, tad uvjek pomisli zašto će ti if dati i odgovor ab-bc.. dok želiš samo bc. Tj to je programerska logika vs ljudska, mi kad vidimo listu logički zaključimo u koji period to spada, dok algoritam mora to imati definirano i ne propustiti prvi podatak koji zadovolji kriterij i tu stati, jer može postojati još odgovora, boljih-točnijih.. tj opet povratak na početak, eliminiraj nagađanje pa time i potrebu za vratolomijama u nagađanju ako možeš.

ihush čet 19.12.2019 15:43

pazi, kad kažeš najbliža, može biti +/- (prije i poslje zadanog vremena)? .. ili samo <= ili >= .. najbliže je i sekunda kasnije, ali ovisno o uvjetima možda nedozvoljeno.

-možeš selektirati beetween.. ali kreni s iteracijama traženja od nultog-zadanog vremena unazad (ili unaprijed) i tad prvi mogući daje točan odgovor, ako sam dobro razumio kriterij BC.. (ne AB-BB.., dok je CC iza neprihvatljiv). Tad nije najbliža nego manje-jednako do.

 

-nedovoljno podataka da bi možda kvalitetno razumijo problem, tj ako kreneš od posljednjeg vremena prvo unazad, tad je prvi odgovor točan (kao sorting Z-A, vs A-Z), ako kreneš od prvog, zadovoljava kriterij ali moraš nastaviti na idući, koji ako zadovolji kriterij postaje važeći (kao sort algoritam) i nastavljaš dalje do zadanog kriterija iteracijama.. idući, .. kao igra anjc, ili je tropa ili je jači-bolji, idući.. do tropa kad se prekida traženje. No zato, zbog optimizacije procesa-algoritma, kreneš unazad, tj tako mi izgleda kao kraći put i time kvalitetnije rješenje (koja u oba slučaja mora dati isti točan odgovor).

 

+ dok je najkvalitetniji način ne biti u takvoj situaciji da se podatak 'traži' nego to mora biti obavjeno prilikom unosa.. i tad ako treba automatika može istu stvar tj algoritam koji bi ovako koristio može jednako biti implementiran kod unosa i tad odmah dok korisnik unosi podatak biti vidljivo.. 'samo nextaš'.. npr kao što svaki formuilar može imati trenutni datum-vrijeme, jednako može biti i ovo vrijeme unešeno, odnosno onaj tko unosi podatak upravo tad to obavi-izmjeni ako je neko drugo vrijeme. Sve ostalo je nagađanje, mada uz logiku možemo pretpostaviti što je točno-moguće a što ne. Ja bi to riješio kod unosa, stvaranja podatka, ako se može. Ako ne išao bi unazad kao optimalan algoritam, tek ako iz nekog razloga nije izvedivo, normalnim od početka, ali ne stati na prvom rezultatu koji zadovolji kriterij jer idući je možda bolji.. kao anjc, do tropa kad se petlja prekida i rezultat je posljednji važeći. + napomena, prvi inicijalni podtak jednako može biti valjan-pogrešan, npr nula-null... tj teško je predpostaviti tip podataka i sve kombinacije koje se mogu desiti na tako malom uzorku i dok ne znam što točno predstavljaju podaci u primjeru.

-prvi uzeti/inicijalni podatak koji tad uspoređuješ kao za sort/bublle neke petlje je nrp vrijednost nula.. ovisno o pronađenoj boljoj vrijednosti, može se takav rezultat dodatno tumačiti, tj if .. then .. jer ne mora uopće biti iz skupine točnih odgovora kao ab-bc-.. može biti aa tj nepostojeći podatak ili nula (za količinu, masu, vrijeme može biti neprihvatljiva vrijednost i sl).

 

edit: .. npr

select * from* where (beetween interval) .. order Z-A i prvi je tad točan odgovor.. Naravno, moguće da će kod biti malo kompliciraniji.. :)

ili ako te muči upravo taj 'interval' kako ga znati? pa ne možeš ako nemaš ništa, početni podatak ili trenutno vrijeme ili bilo koji drugi interval s kojim nešto uspoređuješ, tek kad imaš početni-traženi-uvjetovan možeš tražiti odgovarajući, kao što možeš ključem tražiti bravu i obrnuto, ne ako nemaš ni jedno od to dvoje. ..itd. :)