Hirdetés

2024. május 3., péntek

Gyorskeresés

Útvonal

Fórumok  »  Szoftverfejlesztés  »  SQL kérdések (kiemelt téma)

Hozzászólások

(#5701) Postas99


Postas99
senior tag

Sziasztok!

Lehet nagyon hülyén fog hangazni a kérdés MSSQL adatbáziban lévő 3 különböző táblából szeretnék adatot lekérni * nem vagyok SQL expert* ami a problémám

a tábla
b tábla
c tábla

a.szemelyid , b.azonositoid, b.elemid, b.adat, b.ervenyessegkezdete, b.ervenyessegvege
c.elemid, c.elemnev, c.bookid

Amit szeretnék megoldani az a következő: egy SQL parancsot összerakni úgy hogy egy datagridview-ban egyben lásstam az összes adatot. A többi lekérdezéshez már összeraktam néhány INNER JOINT-ot de itt megakadtam.
A drigviewban amit látni szeretnék az a következő a.nev, a.nem stb ... c.elemnev
Ami alap: a.szemelyid=b.azonositoid, b.elemid=c.elemid
Néhány extra csavar van még a b.azonositoid -hoz több rekordon is van bejegyzés viszont minden egyes bejegyzés esetén a b.elemid más más érték lehet (az érték készlet fix kb 10) mert ezt csak egy referencia érték amit a c.elemidhez tartozó c.elemnev adja meg a valós adat tartalmat.
Tehát szeretném ezekhez a FIX értékekhez az adat tartalmat a datagridview megjelentetni a FIX értékek lehetnek a header-ök. Egy kitétemény van még amennyiben egy FIX érték többször szerepel abbból csak a VALID értéket kell megjeleníteni amit a b.ervenyessegvege mező szabályoz. HA az érték NULL akkor az az adat a valid.

Ha nagyon spongyolán fogalmaztam, akkor elnézést.

Amit eddig összetettem:

SELECT a.csnev , a.knev, a.adoaz, a.szulido, c.elemnev As Neme, b.elemid,alkalmazas.datumtol, alkalmazas.datumig, STUFF((SELECT ', ' + kapcsolat.adatok FROM kapcsolat WHERE kapcsolat.szemelyid = a.szemelyid FOR XML PATH('')), 1, 2, '') AS KapcsolatLista " &
"FROM a " &
"INNER JOIN alkalmazas ON a.szemelyid = alkalmazas.szemelyid " &
"INNER JOIN c ON a.elmid = c.elemid " &
"INNER JOIN b ON a.szemelyid = b.szemelyid "

Ez hoz rendesen találatot de ettől én még felkötöm magam mert ez minden de nem szép és sz@r.

Ebben kérném a segítségeteket.

Köszönöm

[ Szerkesztve ]

(#5702) Postas99 válasza Postas99 (#5701) üzenetére


Postas99
senior tag

Elnézést de a CODE formatot valamiért nem vette be:

SELECT a.csnev , a.knev, a.adoaz, a.szulido, c.elemnev As Neme, b.elemid,alkalmazas.datumtol, alkalmazas.datumig, STUFF((SELECT ', ' + kapcsolat.adatok FROM kapcsolat WHERE kapcsolat.szemelyid = a.szemelyid FOR XML PATH('')), 1, 2, '') AS KapcsolatLista " &
                              "FROM a " &
                              "INNER JOIN alkalmazas ON a.szemelyid = alkalmazas.szemelyid " &
                              "INNER JOIN c ON a.elmid = c.elemid " &
                               "INNER JOIN b ON a.szemlyid = b.szemelyid "

(#5703) sztanozs válasza Postas99 (#5702) üzenetére


sztanozs
veterán

Beveszi az, csak sajnos az uj formazo CODE konvertere eleg bugos, a fejlesztok meg nem nagyon erzik szukseget, hogy kijavitsak...

[ Szerkesztve ]

JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

(#5704) Ispy válasza Postas99 (#5701) üzenetére


Ispy
veterán

Ha támogatja az sql verzió, akkor a for xml-t lecserélheted string_agg-re. Ha nem, akkor csinálhatsz egy subselectet is, ahol eleve összefüzöd a kapcsolatok adatait és már azt rakod be a fő selectbe.

[ Szerkesztve ]

"Debugging is like being the detective in a crime movie where you're also the murderer."

(#5705) nyunyu válasza Postas99 (#5701) üzenetére


nyunyu
félisten

Ebből kb. ennyit sikerült megérteni:
Egy kitétemény van még amennyiben egy FIX érték többször szerepel abbból csak a VALID értéket kell megjeleníteni amit a b.ervenyessegvege mező szabályoz. HA az érték NULL akkor az az adat a valid.

De ezt sem teljesen.

Ha az érvényességre akarsz szűrni, akkor kell a b tábla join feltételei közé (vagy a query végi WHERE-be) egy
b.ervenyessegkezdete >= getdate() AND
nvl(b.ervenyessegvege, getdate() +1 ) > getdate()

(vagy hogy hívják MS SQL-ül az oracles sysdate-et)

Viszont akkor az összes olyan találatot ki fogod szűrni, amihez már csak lejárt b rekordok vannak.
Vagy ha kettőnek nincs lejárati dátuma, akkor mindkettőt megkapod.

Egyébként meg az ilyen adathibák javítására hogy egy b-ből nincs érvényes (vagy több érvényes van), nem az a megoldás, hogy egy feleslegesen túlbonyolított queryvel próbálod kiszűrni őket, hanem kézzel be kéne updatelni az érintett rekordokon az érvényesség eleje, vége dátumokat JÓ értékre, hogy egy időszakra PONTOSAN EGY érvényes rekord legyen.

(Tudom, könnyű ezt mondani, de a rendszerszervezőnknek tavaly nyár óta nincs ideje arra, hogy meghatározza, hogy a többszörös cím, meg telefonszám adataink közül melyik példányt tartsam meg érvényesnek. Közben volt még pár adatmigrációs projekt is, ami extra izgalmakat okozott. :DDD )

[ Szerkesztve ]

Hello IT! Have you tried turning it off and on again?

(#5706) Postas99 válasza Ispy (#5704) üzenetére


Postas99
senior tag

Most azon vagyok hogy lecseréljem mert a verzió támogatja. Visual Studio Vb.net de írhatnám C#-ban is mert a feladat az hogy egy meglévő adatbázisból kell napi szinten egy bizonyos adatcsomagot kiszedni ez idáig 1 óra a kolleganőnek naponta és ha ezt egy háttér progi csinálja helyette és leteszi az adatokat akkor az havi szinten is 40 óra spórolás.

nyunyu:
A dátumra hogy miért igy van megoldva nem tudom de az adatbázisban így van letárolva:
b.szemelyid     b.leiras    b.datumtol     c.elemid    d.datumig
xxx             esemeny1    2021-12-01     valtozat1    2022-02-28
xxx             esemeny1    2022-03-01     valtozat2    NULL

(#5707) Postas99 válasza Postas99 (#5706) üzenetére


Postas99
senior tag

Mindegyik ugyanabban a táblában van. Elrontottam , így korrekt

b.szemelyid     b.leiras    b.datumtol     b.elemid     b.datumig
xxx             esemeny1    2021-12-01     valtozat1    2022-02-28
xxx             esemeny1    2022-03-01     valtozat2    NULL

(#5708) nyunyu válasza Postas99 (#5707) üzenetére


nyunyu
félisten

Próbálom összefoglalni, hogy mit szeretnél:
- A táblához kéne C-nek azt az elemét kapcsolni, ami a B tábla szerint éppen érvényes.

Sima ügy, A-hoz hozzájoinolod a B éppen érvényes rekordját *, aztán ahhoz joinolod a C-t.

Valahogy így:
SELECT a.csnev,
a.knev,
a.adoaz,
a.szulido,
c.elemnev As Neme,
b.elemid,
alkalmazas.datumtol,
alkalmazas.datumig,
kapcsolatok.lista AS KapcsolatLista
FROM a
INNER JOIN b
ON a.szemelyid = b.szemelyid
AND b.datumtol <= getdate()
AND nvl(b.datumig, getdate() + 1) > getdate()
INNER JOIN c
ON b.elemid = c.elemid
INNER JOIN alkalmazas
ON a.szemelyid = alkalmazas.szemelyid
INNER JOIN (SELECT szemelyid,
STRING_AGG(adatok, ',') WITHIN GROUP (ORDER BY adatok) AS lista
FROM kapcsolat
GROUP BY szemelyid) kapcsolatok
ON a.szemelyid = kapcsolatok.szemelyid;

Persze lehetne a nvl(b.datumig, getdate() + 1) > getdate() helyett b.datumig IS NULL-ot írni, de így bolondbiztosabb, meg a későbbiekben sem kell módosítani, ha netán valaki '2099-12-31'-et ír be az érvényesség vége mezőbe.

*: előbb szokás szerint eggyel túlgondoltam, aztán máris az esetleges adathibák jártak az eszemben .
Szakmai ártalom :DDD

[ Szerkesztve ]

Hello IT! Have you tried turning it off and on again?

(#5709) Postas99 válasza nyunyu (#5708) üzenetére


Postas99
senior tag

:R Nagyon Nagyon Köszönöm!

Egyre jár az agyunk, minden amit csinálok bolond és hiba biztosnak kell lennie.

(#5710) Louro


Louro
őstag

Sziasztok!

Egy kis performanciális kérdésem lenne. Sql server 2016-os az alap. Kkb. 5-10GB-os adattáblák. Azokat másolom át napi rendszerességgel. Persze nem sok, de hátha van gyorsabb megoldás.

Először ürítem a táblát (truncate). Indexeket kikapcsolom. SSIS Data Flow segítségével áttöltöm a táblát. Majd a clustered indexet, azután a többi indexet újraépítem.

A maxconcurrentprocess -1 értékre állítva, hogy kimaxoljam a CPU-t. A buffer alaphelyzetben, 10 MB/10000 rekordonként másol.

Mess with the best / Die like the rest

(#5711) tm5 válasza Louro (#5710) üzenetére


tm5
tag

Szerintem jó ez így, max a commit pointot feljebb venném, főleg ha nem túl nagy rekordokról van szól, mondjuk 50 vagy 100k-ra. Én Informatica-t használtam/használok adattöltésekre és általában 100k rekord-ra állítom a commit pointot.

(#5712) Louro válasza tm5 (#5711) üzenetére


Louro
őstag

Kipróbálom. Köszönöm. 12 magos processzor és 32 GB ram és párhuzamosan futnak egyéb dolgok is. Ezért nem akarom teljesen lefoglalni. Ezért hagytam az alapértelmezetten. De kipróbálom majd hétfőn.

Köszönöm!

Mess with the best / Die like the rest

(#5713) Jim74


Jim74
nagyúr

Sziasztok!

Az alábbi "problémára" keresnék megoldást.
Adott egy tábla amiben fogadások vannak. Menetenként több fogadás, melyek kimenetele 1(nyert), vagy 0 vesztett.
Ki kellene listáznom azokat a meneteket, ahol legalább 8 egymást követő fogadás nyerő volt.
Hogy lehetne ezt a legegyszerűbben megoldani?

Köszönöm a segítséget :R.

(#5714) nyunyu válasza Jim74 (#5713) üzenetére


nyunyu
félisten

Van egy táblád, amiben van egy menet_id, egy fogadas_id, meg egy nyert mező?

8x összejoinolod önmagával, menet_id = menet_id, következő fogadas_id = előző fogadas_id+1, nyert mindig 1?

select f1.menet_id,
f1.fogadas_id kezdo_fogadas_id
from fogadas f1
join fogadas f2
on f2.menet_id = f1.menet_id
and f2.fogadas_id = f1.fogadas_id + 1
and f2.nyert = 1
join fogadas f3
on f3.menet_id = f1.menet_id
and f3.fogadas_id = f1.fogadas_id + 2
and f3.nyert = 1
join fogadas f4
on f4.menet_id = f1.menet_id
and f4.fogadas_id = f1.fogadas_id + 3
and f4.nyert = 1
join fogadas f5
on f5.menet_id = f1.menet_id
and f5.fogadas_id = f1.fogadas_id + 4
and f5.nyert = 1
...
where f1.nyert = 1;

Hello IT! Have you tried turning it off and on again?

(#5715) Apollo17hu válasza Jim74 (#5713) üzenetére


Apollo17hu
őstag

LAG() vagy LEAD() függvénnyel megképzel 7 extra mezőt, amik az előző, az azt megelőző stb. ... és végül a héttel korábbi fogadást tartalmazzák. Az így előállt 8 mezőt összeadod egy rekordon, és ahol 8-at kapsz, ott volt a nyolcas nyerő széria (vége).

[ Szerkesztve ]

(#5716) Jim74 válasza nyunyu (#5714) üzenetére


Jim74
nagyúr

Köszi :R és Apollo17hu Neked is.
Igen ilyen oszlopok vannak. Az a baj, hogy egy meneten belül a fogadások száma eltérő lehet, így nem tudom, hogy hányszor kellene joinolnom, vagy hány extra mezőt kellene képeznem.
Valamilyen windowed function kéne, ami egy kumulatív sum--ot, vagy sorszámozást képezne egy menet belül, ha az egymást követő fogadások nyerőek, de nullát venne fel, amikor jön egy vesztes fogadás és a következő nyerő fogadásnál egyről indul.
Ciklust nem szeretnék írni rá, csak worst case, mert nem igazán hatékony szerintem SQL-ben.
Végső cél, hogy meg tudjam mondani, hogy melyik volt a leghosszabb nyerő szériájú menet.

(#5717) Jim74 válasza Jim74 (#5716) üzenetére


Jim74
nagyúr

Közben szerintem sikerült megoldanom. Úgy gondolom, hogy ez egy roppant buta és favágó megoldás, de működik. NyV a fogadás eredménye (0, vagy 1). A sorszam pedig a fogadás sorszáma. Azért indul 20-ról mert az a max fogadás mennyiség egy meneten belül.

select menet,
STRING_AGG(Nyv, '') WITHIN GROUP (ORDER BY menet, sorszam) as Nyv_lista
from fogadas_tabla
group by menet
)
select top 1 menet,
case when Nyv_lista like '%11111111111111111111%' then 20
when Nyv_lista like '%1111111111111111111%' then 19
when Nyv_lista like '%111111111111111111%' then 18
when Nyv_lista like '%11111111111111111%' then 17
when Nyv_lista like '%1111111111111111%' then 16
when Nyv_lista like '%111111111111111%' then 15
when Nyv_lista like '%11111111111111%' then 14
when Nyv_lista like '%1111111111111%' then 13
when Nyv_lista like '%111111111111%' then 12
when Nyv_lista like '%11111111111%' then 11
when Nyv_lista like '%1111111111%' then 10
when Nyv_lista like '%111111111%' then 9
when Nyv_lista like '%11111111%' then 8
else 0 end as Nyero_szeria
from lek1
order by case when Nyv_lista like '%11111111111111111111%' then 20
when Nyv_lista like '%1111111111111111111%' then 19
when Nyv_lista like '%111111111111111111%' then 18
when Nyv_lista like '%11111111111111111%' then 17
when Nyv_lista like '%1111111111111111%' then 16
when Nyv_lista like '%111111111111111%' then 15
when Nyv_lista like '%11111111111111%' then 14
when Nyv_lista like '%1111111111111%' then 13
when Nyv_lista like '%111111111111%' then 12
when Nyv_lista like '%11111111111%' then 11
when Nyv_lista like '%1111111111%' then 10
when Nyv_lista like '%111111111%' then 9
when Nyv_lista like '%11111111%' then 8
else 0 end desc

(#5718) fjanni


fjanni
tag

Sziasztok, kis segítséget kérnék. Adott egy tábla egy adatbázisban ahol szenzor adatokat tárolunk. Minden percben rögzíti egy gázfogyasztásmérő aktuális állását. Tehát van benne egy idő adat és egy szám adat ami folyamatosan növekszik.
Hogyan lehet egy olyan SQL lekérdezést írni, hogy számolja ki a változást a két adat között, tehát az aktális értékből vonja ki az előzőt és így megkapjuk az aktuális fogyasztást. A másik kérdés továbbmenve hogy napi/heti fogyasztás értéket hogyan kaphatok, vagy esetlég két adott időpont közöttit.

(#5719) nyunyu válasza fjanni (#5718) üzenetére


nyunyu
félisten

Tetszőleges két időpont közötti: lekérdezed a két időpont közötti rekordokat, és a max(óraállás)-ból kivonod a min(óraállás)-t, max(időbélyeg)-min(időbélyeg) megmondja, mennyi idő alatt, kettőt osztva megvan az átlag.
(Feltételezve, hogy az óraállás monoton nő, és nincs visszatekeréses buhera.)

Egy perccel korábbihoz képesti változáshoz meg össze kéne joinolnod az aktuális rekordot az eggyel előzővel, és úgy kivonni az óraállásokat, időbélyegeket.
Itt az időbélyeg - 1 perc mint join feltétel nem biztos, hogy járható út, mert nem biztos, hogy kereken percenként van új rekord, inkább be kéne számozni a rekordokat egy row_number() over (order by timestamp)-kel, aztán úgy joinolni a saját rn -1-gyel.

[ Szerkesztve ]

Hello IT! Have you tried turning it off and on again?

(#5720) nyunyu válasza nyunyu (#5719) üzenetére


nyunyu
félisten

Sebtében összetákolt Oracle példa:
create table gazora (idobelyeg timestamp, allas number);

insert into gazora (idobelyeg, allas)
values (systimestamp, 70);

insert into gazora (idobelyeg, allas)
values (systimestamp-1, 65);

with oraallas as (
select idobelyeg,
allas,
row_number() over (order by idobelyeg desc) rn
from gazora
)
select akt.idobelyeg aktualis_ido,
akt.allas aktualis_allas,
elozo.idobelyeg elozo_ido,
elozo.allas elozo_allas,
akt.idobelyeg - elozo.idobelyeg eltelt_ido,
extract(day from (akt.idobelyeg - elozo.idobelyeg)*24*60*60)/60 eltelt_ido_perc,
akt.allas - elozo.allas allas_valtozas,
(akt.allas - elozo.allas)/extract(day from (akt.idobelyeg - elozo.idobelyeg)*24*60*60)/60 atlag_fogyasztas
from oraallas akt
join oraallas elozo
on elozo.rn = akt.rn + 1
where akt.rn = 1;

CTE-ben megfordítottam a számozás irányát, hogy fixen rn=1 legyen a legutolsó rekord, eggyel nagyobb az eggyel régebbi.
join feltételben lévő on elozo.rn = akt.rn + 1 feltétellel tudsz játszani, hogy hány méréssel korábbi rekordhoz képest akarsz eltérést, átlagot számolni.

(interval adattípus miatti típuskonverzióért elnézést, nem lehet értelmesen percre váltani.)

[ Szerkesztve ]

Hello IT! Have you tried turning it off and on again?

(#5721) fjanni válasza nyunyu (#5720) üzenetére


fjanni
tag

Kösz a segítséget, de ez nekem egy kicsit bonyolult, egyszerűbb megoldás nincsen?
Tulajdonképpen nem kell új tábla, csak egy Select ami a táblában lévő adatok mellé kiszámolja az utolsó két oszlopot. Az első három oszlop van a táblában.

Ha a deltaT és deltaC megvan akkor már Group by-al tudok periódusokra összegezni, csak azt nem tudom kiszámolni hogy mennyi a növekmény.

[ Szerkesztve ]

(#5722) nyunyu válasza fjanni (#5721) üzenetére


nyunyu
félisten

Ja, hogy van ID mező, és az egyesével nő?
Úgy könnyű...

Akkor elég a CTE mögötti és select, elozo.id = akt.id +1

Hello IT! Have you tried turning it off and on again?

(#5723) nyunyu válasza fjanni (#5721) üzenetére


nyunyu
félisten

select akt.id,
akt.time aktualis_ido,
akt.counter aktualis_allas,
elozo.time elozo_ido,
elozo.counter elozo_allas,
akt.time - elozo.time eltelt_ido,
extract(day from (akt.time - elozo.time)*24*60*60)/60 eltelt_ido_perc,
akt.counter - elozo.counter allas_valtozas,
(akt.counter - elozo.counter)/extract(day from (akt.time - elozo.time)*24*60*60)/60 atlag_fogyasztas
from oraallas akt
left join oraallas elozo
on elozo.id = akt.id - 1
order by id;

[ Szerkesztve ]

Hello IT! Have you tried turning it off and on again?

(#5724) Jim74 válasza fjanni (#5721) üzenetére


Jim74
nagyúr

A LAG fügvénnyel tudsz hivatkozni előző értékekre
LAG(Counter, 1) OVER (ORDER BY Time)
Ez az adott sor előtt időben eggyel lévő sor Counter értékét adja vissza. Ebből kivonod az aktuális sor Counter értékét és megvan a fogyasztás a két időpont között. Ugyanezt be tudod vetni az időre is csak ott Datediff-et használj a két időpont között eltelt idő kiszámításához.

[ Szerkesztve ]

(#5725) Ispy válasza Jim74 (#5724) üzenetére


Ispy
veterán

Ma is tanultam valamit, én mindig selfjoinoztam eddig, köszi. :DDD ;]

"Debugging is like being the detective in a crime movie where you're also the murderer."

(#5726) Jim74 válasza Ispy (#5725) üzenetére


Jim74
nagyúr

LEAD-del pedig a következő sorokra lehet hivatkozni. ;)
Performancia szempontjából nem tudom, hogy a LEAD/LAG vagy a self join a jobb megoldás, mert sosem teszteltem ezt. Ha vakon kellene fogadnom, akkor a LEAD/LAG-re tennék. ;)
Az is igaz, hogy én csak MS SQL-ben dolgozom, nem tudom, hogy máshol léteznek-e ezek a függvények.

(#5727) Jim74 válasza fjanni (#5718) üzenetére


Jim74
nagyúr

A napi, heti fogyasztást úgy tudod megoldani, hogy képzel két oszlopot a Time mezőből, az egyikben a napok, a másikban az Év-hetek leszenek (azért nem csak hét, mert több éves adasor esetén a különböző évek ugyanazon heteit nem tudnád megkülönböztetni.
Erre a két oszlopra mar tudod group by-olni a fent kiszámított két Time közötti fogyasztási adatokat.
Ha két időpont között szeretnéd kiszámolni, akkor WHERE feltételben korlátozod az intervallumot. (Where Time between x and y).

Nap: CAST(Time as date) as Datum
Év-hét CONCAT(DATEPART(year, Time), '/' , DATEPART(iso_week, Time)) as Ev_het

[ Szerkesztve ]

(#5728) Louro válasza Jim74 (#5726) üzenetére


Louro
őstag

Én Oracle-ben találkoztam vele először. Bár azóta inkább az sql server mellett tettem le a voksom. Szerintem a legtöbb helyen elérhető.
Én úgy szoktam mondani, hogy ha 1-2 alkalommal kell, akkor performancia sokadlagos. Az eredmény legyen jó. De ha már ütemezett feladat lesz belőle, akkor megnézem a végrehajtási tervet és próbálom keresni a költséges pontokat.

Mess with the best / Die like the rest

(#5729) Jim74 válasza Louro (#5728) üzenetére


Jim74
nagyúr

Ssrs dashboard-oknál szoktuk nézni, hogy a dataset query futásideje max. 5 másodperc legyen, mert afelett a felhasználói élmény már sérül.
Ha több, akkor jön az sql tuning.

[ Szerkesztve ]

(#5730) bandi0000


bandi0000
nagyúr

Sziasztok,

Nagyon amatőr kérdés, adatbázis tervet csinálok, ERDPlus-ban, beadandó, szal nem kell semmi részletesség, viszont nem emlékszek a jelölésre N-1 kapcsolat esetén...

Szóval van pl egy tábla Munkalap és Autók, 1 munkalapon 1 autó, viszont több munkalapon is szereplehet ugyan az az autó. Ebben az esetben a diagramon a több kapcsolat jele a munkalapoknál lesz, és az 1 kapcsolat jele pedig az autóknál, vagy fordítva?

Xbox One: bandymnc

(#5731) disy68 válasza bandi0000 (#5730) üzenetére


disy68
aktív tag

1 autóhoz több munkalap

cheat sheet:

“Yeah, well, you know, that’s just, like, your opinion, man.” — The Dude

(#5732) bandi0000 válasza disy68 (#5731) üzenetére


bandi0000
nagyúr

Tehát a több jel jelen esetben a munkalapnál lesz... Köszönöm azt hiszem pont így csináltam, csak valamiért belekavartam magam :D

Xbox One: bandymnc

(#5733) disy68 válasza bandi0000 (#5732) üzenetére


disy68
aktív tag

van, hogy az ember túlgondolja :)

“Yeah, well, you know, that’s just, like, your opinion, man.” — The Dude

(#5734) fjanni válasza Jim74 (#5724) üzenetére


fjanni
tag

Sajnos sem a LAG, sem az EXTRACT függvényt nem ismeri a Mariadb. Egyébként Grafana lekérdezésben használnám, ahol csak azokat a mezőket kellene a selectbe betenni amit ábrázolni is akarok. Azaz ez esetben két adat kellene, az időbélyeg (ami megvan - time) és a számított eltérés az előző rekordhoz képest (a jelenlegi és az előző óraállás különbözete)

(#5735) Jim74 válasza fjanni (#5734) üzenetére


Jim74
nagyúr

Sajnos a Mariadb-t nem ismerem, de egy gyors keresés alapján elvileg ismeri a LAG fügvényt.
[link]

(#5736) Jim Tonic


Jim Tonic
nagyúr

Sziasztok, jó régen jártam erre. TSQL.
1: N táblakapcsolat. A lekérdezésben az egyik mezőben 1-től N-ig kellene léptetni egy számlálót. A bal táblán a következő rekordra lépve újra egyről indul.
Tudtok erre egyszerű megoldást?
Köszönöm.

Alcohol & calculus don't mix. Never drink & derive.

(#5737) Jim74 válasza Jim Tonic (#5736) üzenetére


Jim74
nagyúr

Szia!
dbo.getnums táblát visszaadó függvénnyel tudsz 1-től n-ig léptetni.
A másik kérdést kifejtenéd példával, mert ennyiből nem teljesen világos számomra.

[ Szerkesztve ]

(#5738) Jim74 válasza lm83 (#5601) üzenetére


Jim74
nagyúr

Köszi. :R

[ Szerkesztve ]

(#5739) tm5 válasza Jim Tonic (#5736) üzenetére


tm5
tag

ROW_NUMBER() OVER (       PARTITION BY <<join mező, vagy az 1. tábla kulcsa>>    ) row_num

Ha lenne egy példa struktúrád akkor könnyebben el lehetne magyarázni...

(#5740) Jim74 válasza Jim74 (#5738) üzenetére


Jim74
nagyúr

Ezt nem ide akartam, félrement. :DDD

(#5741) Jim Tonic válasza tm5 (#5739) üzenetére


Jim Tonic
nagyúr

Fejből példa. Legyenek a bal oszlopban a megrendelés fejek, a jobb oszlopban pedig a pozíciók.
Kulcs:
- OrderNr
Bal oszlop:
- OrderNr
- Date
Jobb oszlop:
- OrderNr
- Part
- Qty

Ezeket kell lekérdezni, és akkor LineNr legyen a pozíció száma, ami nyilván OrderNr-enként újra kezdődik.

Alcohol & calculus don't mix. Never drink & derive.

(#5742) Jim74 válasza Jim Tonic (#5741) üzenetére


Jim74
nagyúr

SELECT *,
ROW_NUMBER() OVER (PARTITION BY OrderNr ORDER BY Part)
FROM jobb_tabla

Ha kell a megrendelés dátuma is, akkor join-olod a rendelés fej (törzs) táblát a fenti lekérdezésben

[ Szerkesztve ]

(#5743) tm5 válasza Jim74 (#5742) üzenetére


tm5
tag

+1

(#5744) Jim Tonic válasza Jim Tonic (#5741) üzenetére


Jim Tonic
nagyúr

Oszlop = tábla, csak már elfelejtek magyarul. :B

Jim74, tm5, nektek pedig nagyon köszönöm. :)

Alcohol & calculus don't mix. Never drink & derive.

(#5745) Pulsar


Pulsar
veterán

Sziasztok,

van egy kérdésem. Megpróbálom egy kis példával szemléltetni, mert leírni nem tudom. Légyszi ne öljetek meg nagyon, nem vagyok nagy SQL mágus, kisebb lekérdezésekkel elboldogulok, és ennyi, de szívesen tanulok :)

Adott 3 tábla, benne adatok. Lehetnek benne más adatok de azok nem relevánsak.

tabla_1
ID NAME
1    A
2    B
3    C
4    D
5    E
6    F
7    G
8    H

tabla_2
ID    Created_date    ID2
1    2022.01.01        11
2    2022.01.01        18
3    2022.01.02        31
4    2022.01.02        55
5    2022.01.01        77
6    2022.01.03        110

tabla_3
ID    Description
11    Alma
55    Körte
77    Szőlő
110    Répa
Az adatok amiket le kell kérdezni: A, B, C, D, E, F, G

Eddig így oldottam meg (tudom ez a fajta join sem a legjobb, de gyors, és hatékony számomra):
select temp2.tempname, temp2.tempid, temp2.id, temp2.id, temp2.created, temp2.id2, t3.Description
FROM
tabla_3 t3
(select temp.name tempname, temp.id tempid, t2.ID id, t2.Created_date created, t2.ID2 id2
FROM
tabla_2 t2,
(select NAME name, ID id
FROM
tábla3 t3,
IDs ids
where
ids.column1 = tabla_1.name) temp
whre
temp.id = t2.id) temp2
where
t3.id2 = temp2.id2

A select így lefut (lehet van benne elírás, azért bocs), de csak arra kapok eredményt, ahol mindhárom táblában van találat. Én úgy szeretnék lekérdezést futtatni, hogy ahol nincs eredmény, ott is legyen visszakapott eredményem, mondjuk NINCS, vagy bármi.

Pl ilyesmit:
A 2022.01.01 Alma
B 2022.01.01 NINCS
C 2022.01.02 NINCS
D 2022.01.02 Körte
E 2022.01.01 Szőlő
F 2022.01.03 Répa
G NINCS NINCS

Remélem érthető amit szeretnék kérdezni, és semmi szentségtörést nem írtam le :)

(#5746) Jim74 válasza Pulsar (#5745) üzenetére


Jim74
nagyúr

Szia!

Nem ölünk meg senkit, aki nem sql pro :DDD . Azért van a fórum, hogy segítsünk, tapasztalatot osszunk meg. Én is csak a felszínt kapargatom és még élek. :DDD

select * from tabla_1 t1
left join tabla_2 t2 on t1.ID = t2.ID
left join tabla_3 t3 on t1.ID = t3.ID

Bocs a formázásért telefonról vagyok.
Elvileg így minden sor lejön minden táblából és ahol nincs találat, ott NULL értékeket fogsz kapni.
Ha rosszul értelmeztem az igényt, akkor sorry.

[ Szerkesztve ]

(#5747) Jim74 válasza Jim74 (#5746) üzenetére


Jim74
nagyúr

Természetesen a * helyére az általad megjeleníteni kívánt mezőket írd be.

(#5748) Pulsar válasza Jim74 (#5747) üzenetére


Pulsar
veterán

ó, köszönöm szépen, ezt ki fogom próbálni :)

(#5749) Jim74 válasza Pulsar (#5748) üzenetére


Jim74
nagyúr

Pontosítok, tabla_1-ből minden jön, a többiből, ahol van találat, de ahol nincs ott is megjelenik a tabla_1 rekordjai, csak a többi táblából megjelenített érték azokon a sorokon NULL érték lesz.
Ha a NULL kiírás nem megfelelő, akkor az ISNULL függvénnyel tudod tetszőleges értékre cserélni.
Pl. ISNULL(t2.Created_date, 'NINCS')
Ekkor, ha a tabla_2-ben nincs tabla_1 ID-hez kapcsolható rekord, akkor a Created_date oszlopban a NULL érték helyett NINCS érték fog megjelenni.

(#5750) Pulsar válasza Jim74 (#5749) üzenetére


Pulsar
veterán

szuper, bármi jó nekem, köszönöm
Egy kérdésem lenne még. Az általad írt példánál ha minden tábla valójában sokkal összetettebb mint amit példának hoztam, és a selectem teli van WHERE feltéttel, azt ezesetben hova kell írni? :)

Útvonal

Fórumok  »  Szoftverfejlesztés  »  SQL kérdések (kiemelt téma)
Copyright © 2000-2024 PROHARDVER Informatikai Kft.