- Samsung Galaxy S24 Ultra - ha működik, ne változtass!
- iPhone topik
- Samsung Galaxy S23 és S23+ - ami belül van, az számít igazán
- Samsung Galaxy Watch (Tizen és Wear OS) ingyenes számlapok, kupon kódok
- Küszöbön a One UI 8 béta program
- Jövőre az Apple megérkezhet 2019-be
- Google Pixel topik
- Redmi Note 10 Pro - majdnem minden stimmel
- Poco X6 Pro - ötös alá
- Poco F5 - pokolian jó ajánlat
Új hozzászólás Aktív témák
-
nyunyu
félisten
válasz
DeFranco #4699 üzenetére
Csak tipp: felső selecthez hozzájoinolod az egyedenkénti szummát egy új oszlopba, majd ezzel az értékkel osztod lent a sum(ertek)-et?
select * from (
with egyed_osszeg as
(select egyed_azonosito,
sum(ertek) osszeg
from tabla
group by egyed_azonosito)
select t.egyed_azonosito,
t.csoport_kepzo,
t.ertek,
o.osszeg
from tabla t
join egyed_osszeg o
on t.egyed_azonosito = o.egyed_azonosito
)
pivot
( sum(ertek)/osszeg
for csoport_kepzo in ('A','B'...)
) -
DeFranco
nagyúr
Sziasztok,
Oracle SQL developert használok és az alábbi feladatot szeretném megoldani.
Adott egy pivot-olt lekérdezés, amivel lejön egy kereszttábla, adatokkal.
Példa:
SELECT * FROM
(
SELECT
[EGYED AZONOSITO],
[CSOPORT KEPZO],
[ERTEK]
FROM
[TABLA]
)
PIVOT
(
SUM([ERTEK])
FOR [CSOPORT KEPZO] IN ([A],[B],[C],[...],[Z])
)Tehát ERTEK összesített adatait CSOPORT KEPZO szerint egymás mellé pakolja minden EGYED AZONOSITO esetén.
Szeretném mellé tenni egy másik kereszttáblába azokat az indexeket, amik úgy képződnek, hogy az EGYED AZONOSITO szerint minden ERTEK-et összeadok CSOPORT KEPZO-től függetlenül és ezzel a fenti tábla megfelelő sorának minden értékét elosztom.
Példa:
Első pivot:
Béla 0,0,15,0,0,30,0,15
Második pivot:
Béla 0,0,0.25,0,0,0.5, 0,0.25
Hogyan tudom ezt megoldani?
-
RoyalFlush
őstag
Elsőre azt gondoltam, hogy az egymást követő rekordokra vonatkozó lekérdezés lefedi az esetek egészét, de ez végül téves feltételezésnek bizonyult a részemről és a Descartes-szorzatot használó megoldás több keresett találatot eredményezett. Úgyhogy bambano, tm5 köszönöm szépen mindkettőtöknek
-
nyunyu
félisten
Probléma az, hogy a WHERE után írt feltétel az globális.
Ha oda azt írja, hogy t19.ertek>19, akkor minden olyan rekordot vissza fog adni, ahol ez teljesül.
NULL értékekre definíció szerint <,=,> hasonlítás sem teljesül, emiatt kiszűri azokat, ahol csak a T20 táblában lenne jó érték, de a T19-ben nincs.LEFT/RIGHT/FULL JOINkor emiatt fokozottan figyelni kell a NULLokra.
Tehát valami ilyesmit tud csinálni, hogy
where (t19.ertek is null OR t19.ertek>19)
and ... többi feltétel. -
-
-
nyunyu
félisten
Lehet, hogy az első logikája érthetőbb lenne CTE szintaxissal:
with utolso_tankolas as
(select rendszam,
max(datum) max_datum
from tankolas t
group by rendszam)
select
t.datum,
t.rendszam,
t.km
from tankolas t
join utolso_tankolas t2
on t.rendszam = t2.rendszam
and t.datum = t2.max_datum; -
nyunyu
félisten
válasz
Petya25 #4684 üzenetére
Először le kéne válogatni rendszámonként az utolsó dátumot, majd azokhoz a rendszám-dátum párosokhoz tartozó km értéket kikeresni a táblából.
Alselect helyett joinnal:
select
t.datum,
t.rendszam,
t.km
from tankolas t
join (select rendszam,
max(datum) max_datum
from tankolas t
group by rendszam) t2
on t.rendszam = t2.rendszam
and t.datum = t2.max_datum;Vagy rendszámonként besorszámozod dátum szerint csökkenőbe, és minden rendszámhoz az első rekordot veszed:
select datum,
rendszam,
km
from (select datum,
rendszam,
km,
row_number() over (partition by rendszam order by datum desc) rn
)
where rn=1;Egyébként ha meg feltételezzük, hogy a km állás monoton növekvő (magyarul nem szokták babrálni az órát), akkor egyszerűbben is lehet, hiszen a max(datum) és a max(km) érték ugyanazon a rekordon kéne hogy legyen:
select rendszam,
max(datum) datum,
max(km) km
group by rendszam;De ilyet ne feltételezzünk, mert a valóság az, hogy ahány adatrögzítő, annyiféleképpen sikerült bevinnie az adatot az évek során.
-
Petya25
őstag
Biztos csak én nem látom a fától az erdőt...
A max dátumhoz tartozó km kellene rendszámonként (mssql)SELECT MAX(Datum), Rendszám, Km
FROM tankolas
GROUP BY Rendszám, Km -
user112
senior tag
Sziasztok!
Évente külön táblában (T20, T19 stb) tárolt KOD, TIPUS, ÉRTÉK adatokat szeretnék lekérni:
KOD, TIPUS, ÉRTÉK_19, ÉRTÉK_20, változás%
formában, hogy az azonos KOD és TIPUS adatok egy sorban legyenek és akkor is megjelenjen, ha csak az egyik táblában szerepel (Oracle).
Köszönöm. -
nyunyu
félisten
Egyáltalán kell egy plusz lekérdezés az Oracle specifikus from dual szintaxissal?
Nem lenne egyszerűbb egy
select nvl(count(*),0) from tablanev;[szerk:]Hmm,Oracle 11G2 amúgy is 0-t ad vissza count(*)-ra, ha nincs egy rekord se a táblában, nem NULL-t.
-
Sziasztok,
Van egy selectem ami count-ol. Tök jól is működik. Viszont előfordul olyan is, hogy nincs a selectnek eredménye. Meg tudom az csinálni valahogy hogyha nincs eredmény, akkor a visszaadott érték 0 legyen, ne pedig semmi?
Egy excel macroval futtatom a selectet, és elég zavaró a semmi :D -
Louro
őstag
válasz
RoyalFlush #4664 üzenetére
Mondjuk már engem is érdekel a pontosítás. Csak egymást követőek a kérdésesek vagy a teljes tábla?
Ebben az esetben
- ha csak az előzővel kell összehasonlítani, akkor a LEAD vagy LAG megoldás jó lehet. De 3. és 4. sor nem lesz hiba. Hisz növekszik a dátum.
- ha a teljes táblára kell nézni, azaz ha van olyan dátum a megelőző sorokban, ami kisebb, akkor az összes olyan sort adja vissza, akkor a Descartes szorzat a nyerő. A példában a legkisebb a 2020.01.01, így minden előtte levő hibás.Első esete szerintem azért nem lesz jó, mert ha kijön, hogy a 3. sorban lévő dátum kisebb, mint az előtte levő, azt lehet javíttatod. Majd újra futtathatod, amíg az összes sort rendbe nem teszik.
Ha nincs 2-300000 sor a tábla, lehet kitenném Excel-be a felhasználóknak és tennék rá egy feltételes formázást, =B2<B3, azaz ha kisebb a Dátum mező az előzőnél, akkor színezze ki nekik. A felhasználók többsége imádja a színeket.
-
Szmeby
tag
Értem, és köszönöm a választ. Én is szeretem elszeparálni egymástól a lazán kapcsolódó dolgokat. SRP FTW!
Az mondjuk valóban egy fontos kérdés, hogy mi lehetett a kérdező szándéka. Tök érdekes látni, hogy ennek hiányában két egészen eltérő megoldás is született. Az, hogy nem akarja szemmel verni, mindkét esetben teljesül. De hogy ezután mihez kezd velük... arra lehet, hogy egy harmadik megoldás lesz az ideális.
-
tm5
tag
válasz
bambano #4670 üzenetére
Hát a lenti feladatleírás alapján ha az ID nő akkor a DATUMnak is növekvőnek kell lennie.
Tehát ha ID1 < ID2 < ID3 < ID4 < ID5... akkor DATUM1 < DATUM2 < DATUM3 < DATUM4 < DATUM5... az elvárt állapot. Ezek alapján szerintem fölösleges a DATUM5-t mondjuk a DATUM2-vel hasonlítani, elég csak DATUM4-gyel, mert nem hiszem, hogy van olyan eset, hogy kisebb lenne DATUM2-nél de nagyobb mint DATUM4.
Szóval igen, ez csak egymás utáni párokat vizsgál, de szerintem ez elég.
Szmeby:
Én szeretem használni a WITH-et, mert jobban elszeparálja az egyes logikákat egymástól. Jelen esetben akkor a teljes LEAD-es részt bele kellett volna tenni a WHERE-be is, mert ugye ugyanazon queryn belül nem tudod a SELECT-ben megadott aliasokat a WHERE feltételben használni. Szóval így szebb és érthetőbb.
A next_id azért kellett, mert így látod, hogy melyik két egymást követ ID-nál van gond a dátumokkal. De elhagyható...Szerintem ez jóval gyorsabb (vagy csak "olcsóbb" ha nem nagy a tábla), mint egy Descartes szorzat. Én napi szinten használok analitikus SQL kifejezéseket millió soros táblákon Oracle-ben és szerintem nagyon jól optimalizált a futtató mögötte. Tény, hogy ebbe az Exadata is besegít.
-
bambano
titán
szerintem ez a megoldás nem a kérdésre ad választ, mert ez csak azt mondja meg, ha két egymásutáni rekordnál rossz a dátum sorrendje, azt nem, hogy két tetszőleges rekordnál is az.
tehát ha van egy id=300, datum='2019-07-30' rekordod, azt a te megoldásod nem találja meg, az enyém igen. a kérdés, hogy a kérdező mit akart kérdezni
-
Szmeby
tag
válasz
Apollo17hu #4668 üzenetére
Köszi Apollo! Fantasztikus ez az Oracle.
És tm5 azért csomagolta egy WITH-be, mert WHERE mögött ezek az analitikus cuccok nem használhatók, csak projekcióban (vagy hogy is hívják a from előtti részt)?
A next_id kiszámításának van valami különleges oka, vagy az amúgy elhagyható? Én feleslegesnek érzem az aktuális probléma szempontjából. Hacsak az oracle belső mechanizmusai ezt mégis megkövetelik valami mágikus okból.
Ez a megoldás amúgy a Descartes szorzathoz képest milyen előnyöket nyújt? Gyorsabb? Kíméli a memóriát? Elegánsabb?
A paraszti eszem azt súgja, hogy nem igazán lehet gyorsabb, hiszen ígyis úgyis kétszer szelektál a táblából, csak más sorrendben teszi a folyamat során. Hacsaknem attól ér el gyorsabb működést, hogy a nyers adatok diszken való rendezettségének köszönhetően a vinyó kevesebb fejmozgással is végre tudja hajtani a lekérdezést egy nagy adathalmazon. Bááár, azzal, hogy az eredeti halmazon nincs orderby, a lead függvény meg sorrendezett halmazon operál, még ez sem feltétlenül biztos. Asszem elkalandoztam. -
Apollo17hu
őstag
A LEAD függvénnyel olyan oszlop hozható létre, ami egy meglévő mező csoportosított/sorbarendezett értékeit eltolja.
tm5 megoldásában a halmaz nincs csoportosítva, csak ID alapján sorbarendezve. E szerint az ID és a DATUM mezőket egy rekorddal eltolva képzi meg a next_id és next_datum oszlopokat.Alapértelmezettként az eltolás mértéke 1, ekkor elhagyható.
A LEAD-hez hasonló még a LAG függvény, ahol az eltolás "ellenkező" irányba történik. -
tm5
tag
válasz
RoyalFlush #4664 üzenetére
Analitikus függvényekkel is neki lehet esni és akkor nem kell descartes szorzat:
WITH src AS (
SELECT
id
, datum
, LEAD(id) OVER ( ORDER BY ID ) next_id
, LEAD(datum) OVER ( ORDER BY ID ) next_datum
FROM datumok)
SELECT *
FROM src
WHERE datum > next_datum -
bambano
titán
válasz
RoyalFlush #4664 üzenetére
valahogy így:
select t1.*,t2.* from datumok t1, datumok t2 where t1.id>t2.id and t1.datum<t2.datum
fejből írtam, nem biztos, hogy szintaktikailag helyes.
-
RoyalFlush
őstag
Sziasztok!
A segítségeteket szeretném kérni (Oracle PL/SQL).
Van egy tábla (DATUMOK) az alábbi oszlopokkal:
ID
DATUMAzt szeretném lekérdezni, hogy mely rekordoknál fordul az elő, hogy kisebb ID-val, de nagyobb DATUM értékkel szerepel, mint egy másik.
Példa:
ID DATUM
100 2020-01-01
200 2019-06-30
Hogyan lehetséges ezt lekérdezni, hogy ne szemmel veréssel kelljen összehasonlítgatni, vannak e ilyen sorok a táblában és melyek?
Köszönöm!
-
nyunyu
félisten
Akár alselectet is lehetett volna írni:
SELECT *
FROM items
WHERE type=477
AND status='OPEN'
AND id in (SELECT id
FROM items
GROUP BY id
HAVING COUNT(*) = 1)Elvileg ez ekvivalens az előző, joinolt megoldással.
#4660: Szerintem a kérdés direkt van ilyen egyszerűre fogalmazva, hogy meg lehessen oldani subquery meg analitikus függvény nélkül.
Szerintem meg észre kéne venni, hogy ez a feladat két lépésből áll, először leválogatni az egyelemű tételeket, majd azokon szűrni.
Ha egy selectben szűrsz és számolsz, akkor fals eredményt fogsz kapni, mivel a szűrt eredményhalmazt fogja megszámolni, nem a teljes táblát.
(Először a WHERE értékelődik ki, és csak utána a HAVING)-> vagy alselect vagy join kell.
-
bpx
őstag
A kérdés az volt, hogy azok a sorok kellenek amelyek ID-ja csak egyszer szerepel a táblában, továbbá igaz rájuk, hogy status = open, type = 477.
Nálad a status = open, type = 477 szűrés az aggregráció előtt történik, mert az a WHERE-ben van, nem a HAVING-ben.
Emiatt ha pl. így néz ki a tábla, akkor az eredményedbe mindkettő sor bekerül:
id | status | type
--------|--------|------
1 | open | 477
1 | closed | 476Erre nem teljesül az, hogy az ID csak egyszer szerepel, hiszen 2 sorban is ott van, és mivel csak az ID alapján történik a self join, visszadja az ID-hoz tartozó összes többi sort is, amelyekre a status = open, type = 477 nem teljesül.
A min(status) meg min(type) részhez annyi, hogy a having count(*) miatt eleve csak az 1 tagú csoportokat vizsgáljuk, ahova mindegy, hogy min vagy max vagy más csoport függvényt írok, de valamit muszáj, hogy megegye az aggregráció + having. A havingben ott van utána még a számunkra szükséges szűrés, ez az aggregáció után történik, és az 1 elemű csoportokból csak a nekünk szükségeseket hagyja meg.
Szerintem a kérdés direkt van ilyen egyszerűre fogalmazva, hogy meg lehessen oldani subquery meg analitikus függvény nélkül.
Új hozzászólás Aktív témák
- Gitáros topic
- Wiz Khalifa: Grand Theft Auto VI - Érdekességek, látványosságok, képek, infók egy helyen.
- LEGO klub
- Samsung Galaxy S24 Ultra - ha működik, ne változtass!
- Robot fűnyírók
- Magga: PLEX: multimédia az egész lakásban
- iPhone topik
- Samsung Galaxy S23 és S23+ - ami belül van, az számít igazán
- Amlogic S905, S912 processzoros készülékek
- Le Mans Ultimate
- További aktív témák...
- Bomba ár! Fujitsu LifeBook U758 - i5-8GEN I 8GB I 256GB SSD I HDMI I 15,6" FHD I W11 I Garancia!
- Xiaomi Redmi A2 32GB, Kártyafüggetlen, 1 Év Garanciával
- Telenor 5G Indoor WiFi Router (FA7550) + töltő
- LG 27GR95QE - 27" OLED / QHD 2K / 240Hz & 0.03ms / NVIDIA G-Sync / FreeSync Premium / HDMI 2.1
- Bowers/Wilkins Px7 S2 fejhallgatók
Állásajánlatok
Cég: PCMENTOR SZERVIZ KFT.
Város: Budapest