- Motorola Edge 50 Neo - az egyensúly gyengesége
- iPhone topik
- Samsung Galaxy S23 Ultra - non plus ultra
- Apple iPhone 16 Pro - rutinvizsga
- Honor Magic6 Pro - kör közepén számok
- Xiaomi 14T Pro - teljes a család?
- Megjelent a Poco F7, eurós ára is van már
- Yettel topik
- Sokat fejlődött a Tecno belépő ajánlata
- Samsung Galaxy Watch7 - kötelező kör
Új hozzászólás Aktív témák
-
Taci
addikt
Ezért is fontos a QA.
Meg a lomtár.
Én most egy kicsit értetlenül is álltam a dolog előtt, mert egy ilyen hibát észrevettem volna ennyi idő alatt (már kerestem egy ideje, nem egyből ide jöttem segítséget kérni).
Aztán rájöttem, hogy egy régi lekérdezést mutattam példának, azt átalakítva a problémához - viszont a problémás lekérdezés nem ez volt...
Szóval most átírtam a példához újra: DB Fiddle
De hátha ez is egy teljesen egyértelmű hiba részemről csak, hogy itt nem úgy működik, ahogy szeretném.
Ránéznél, kérlek?
-
Taci
addikt
A category_id-ra szükségem van, nem szedhetem ki. (De amúgy a teszt kedvéért kivettem, és semmi sem változott, se a sebesség, se a distinct nem hozta a kívánt eredményt.)
Annyit találtam, hogy ha használom a GROUP BY-t is, akkor a megfelelő eredményeket kapom, és valamelyest gyorsul a lekérdezés is. (És DISTINCT-tel vagy anélkül is ugyanazt a (jó) eredményt adja, szóval így a DISTINCT talán nem is kell.)
select p.*
from product p
join product_category pc1
on pc1.product_id = p.id
join category c1
on c1.id = pc1.category_id
where c1.name in ('sárga', 'piros', 'kék')
group by p.id
order by p.date desc;
Így a korábbi ~20 mp helyett már megvan ~9 mp alatt.
És az explain-je is sokkal jobban néz ki:
De a 9 mp még mindig szörnyű.
Merre tovább?
Vagy ez nem is a jó út?
Az adatbázis szerkezete a hibás?
Vagy a lekérdezés?Jelenleg nyitott vagyok a teljes adatbázisszerkezet átalakítására is. Egyszer már megcsináltam a javaslatotokra, megcsinálom megint, ha kell. Csak működjön végre.
Mindenesetre keresgélek még, hátha találok ilyen hasznos dolgot, mint a group by. Bár néztem már annyi mindent, millió stackoverflow-bejegyzést...
-
Taci
addikt
Sajnos kb. pont ugyanez a kód (illetve a saját kiegészítéseddel ugyanez), amit írtál (és ami sztanozs tanácsára ki lett egészítve DISTINCT-tel), ez fut le eszméletlen lassan.
Bemásolom, hogy ne kelljen visszakeresni, és kiegészítem a DISTINCT-tel:
select distinct p.*
from product p
join product_category pc1
on pc1.product_id = p.id
join category c1
on c1.id = pc1.category_id
where c1.name in ('sárga', 'piros', 'kék')
order by p.date desc;
Ha benne van együtt a DISTINCT és az ORDER BY is, akkor ~20 mp, ha csak az egyik, akkor 0,05 mp a futási idő.
Plusz a DISTINCT nem is működik (úgy, ahogy elvárnánk), mert ha a product_category táblában egy id-hoz több category_id is van (és van, mert ezért lett ez a tábla létrehozva), akkor annyiszor listázza a product-ból az id-t. (Pedig pont ezért lenne használva, hogy egy id-t csak egyszer listázzon.)
A profiling opciót bekapcsolva ezt látom, ami "fura":
- Copying To Tmp Table On Disk: 18.9 s
- Sorting Result: 1 s
Tehát csak ez a 2 lépés 19.9 másodpercbe kerül, ha van DISTINCT és ORDER BY is.Ha csak az ORDER BY van, akkor:
- nincs Copying To Tmp Table On Disk lépés
- Sorting Result: 6 µsHa csak a DISTINCT van, akkor:
- Copying To Tmp Table: 2.8 ms
- nincs Sorting Result lépésAhogy utána olvastam, azt írják, hogy a DISTINCT és az ORDER BY is sorba rendez, és nem szeretik egymást. Azt is írják, hogy ha az egyiket használom, akkor a másikat valószínűleg nem kell. De hát ez itt nem igaz, mert a DISTINCT azért kell, hogy 1 id csak egyszer jelenjen meg (ami amúgy most sajnos nem igaz, ahogy feljebb írtam is), az ORDER BY meg azért, mert időrendi sorrendben van szükségem a találatokra.
Nagyon nem tudom, merre tovább. Követtem a tanácsaitokat, megcsináltam és átírtam mindent, ahogy javasoltátok, (amit köszönök ez úton is), de sajnos valami még nem kerek, és magamtól nem találok megoldást rá.
Higgyétek el, ég az arcom, hogy ennyiszer kell írnom, és segítségért kuncsorognom - nem jókedvemből teszem. Felajánlottam, hogy fizetek is a szaktanácsadásért és a segítségért, csak végre haladhassak, mert már 1 hónapja egy helyben veszteglek - de sehonnan nem kapok segítséget, sehol egy szakember.
-
Taci
addikt
Megcsináltam mindent, amit javasoltatok, pont úgy, ahogy javasoltátok. Készen és beállítva az új táblák, rendben a kapcsolatok az indexek, és a rekordszám is feltornázva 500e fölé (a kategória-elem kapcsolatok száma 800e körül).
És így a javasolt a JOIN-os lekérdezés ideje: 25 másodperc...
A régi, pazarló LIKE-os lekérdezés ideje: 0.3 másodperc (egy picit javítva a LIKE-os módon már csak 0.01 másodperc)...Nem értem.
Csak "érdekességként" írtam ide (bár nekem bosszúság), már találtam valakit, aki remote-ban tud segíteni - bár ő is pont ugyanezt a JOIN-os módszert mondta, miután átnézne a tábláimat.
-
Taci
addikt
Megcsináltam így, működik is szépen, aktívak az indexelések is.
Viszont így már nem tudom ugye duplikálni a rekordokat, mert a másik táblában (ahol a rekordokhoz tartozó kategóriák vannak tárolva) már nem lehet olyan könnyen.
Szóval most egyelőre 159 rekord van.És amiért most írok:
Összehasonlításként futtatom a régi lekérdezést (LIKE '%category%'
stb.) és az új lekérdezést (JOIN
).És az a régi:
- egyrészt dupla olyan gyors (sőt, 0.0112 vs 0.0266 seconds),
- másrészt az Explain szerint csak a szükséges 4 rekordot ellenőrzi/használja (rows: 4) az indexelés miatt (a 159 helyett).Hogy van ez akkor?
A sebesség talán most még az alacsony rekord szám miatt lehet, később, sokkal több elemnél ez talán majd fordul?
Viszont Ti is azt írtátok, és én is azt találtam, hogy ha a LIKE operátor %sztring formában van használva, akkor a teljes táblát használja.
Itt akkor rows: 4 helyett nem rows: 159-nek kellene lennie?Bocsánat a sok kérdésért, de ha már így alakult, hogy saját kezüleg kell csinálnom, szeretném érteni a miérteket. És köszönöm, ha válaszoltok, tanácsot adtok.
(És továbbra is szívesen fizetnék a segítségért, a mostani struktúra átnézéséért, módosítására javaslatért, tanácsokért stb., csak hogy biztos lehessek az erős és stabil alapban.)Köszönöm.
-
Taci
addikt
Sikerült egy úgy-ahogy rendszert összeraknom, megcsináltam a táblát, feltöltöttem ugyanúgy, ahogy otthon is tenném, minden ugyanaz, kivéve, hogy most csak 20 elemet raktam bele, hogy tudjam kézzel szerkeszteni az ajánlott új táblákat is, és ne menjen rá túl sok időm.
Kész mind a három tábla, mondom akkor indexelem a dátum mezőjét (ahogy otthon is tettem), és lekérdezem EXPLAIN-nel, hogy jól dolgozik-e, elsőre csak az alap lekérdezéssel, hogy legyen összehasonlítási alapom:
EXPLAIN SELECT * FROM table ORDER BY date DESC LIMIT 4
Az otthoni rendszerben ez visszaadta, hogy
rows: 4, type: index.
Most azonban hiába ott van az indexelés (phpMyAdmin-ban egyértelműen látszik több formában is), ez a visszatérési érték:rows: 20, type: all.
Tehát nem indexelt semmit.
Próbáltam kézzel is (CREATE INDEX table_date_ix ON table(date)
), illetve grafikus felületen a megfelelő kapcsolóval. De ugyanaz az eredmény.Mi lehet ennek az oka? Túl kevés a 20 elem az indexeléshez? (Otthon 500e rekord volt a táblában, itt most csak 20.)
1. update:
Kíváncsiságból "felduplikáltam" kb. 100e rekordig, és most márrows: 4, type: index.
Ezek szerint a 20 kevés volt? Mennyi a "minimum limit"? Kézzel kell egyelőre dolgoznom, szóval nem mennék nagyon túl a minimumon, ha nem muszáj (és ha van ilyen, persze).2. update:
Visszatöröltem 20 rekordig, és most még mindig van indexelés...rows: 1, type: index.
Ezt nem értem.
Itt azon kívül, hogy hogyan és miért lett hirtelen indexelés ugyanannyi elemre, azon kívül még azt nem értem, a rows értéke miért csak 1, amikor a lekérdezés (explain nélkül) 4 rekordot ad vissza. A rows: 1 pedig ugye azt jelenti, hogy 1 rekordot vizsgált át.
Hogyan ad vissza 4 rekordot, ha csak 1-et vizsgált át?El tudnátok magyarázni, kérlek?
Köszi.
-
Taci
addikt
Nagyon szépen köszönöm a tanácsokat, segítséget, a részletes példákat! Lesz mit átnéznem, értelmeznem és kipróbálnom.
Eljöttem pihenni/nyaralni 3 hétre, szóval lassabban tudok csak reagálni, és egyelőre "vasam" sincs még ezeket a tippeket kipróbálni sem, de szerzek valamit, és ha nem bánjátok, utána kérdezek még.
Nem webshop-motort fejlesztek, azt csak a Te példád miatt vittem tovább (product). RSS feed-ekből szedem ki az adatokat (cím, rövid tartalom, kép, link, illetve kategória), majd ezek az adatok mennek adatbázisba. Itt kerül képbe a kategória, mert van, hogy 1-1 feed elemhez több kategória is tartozik (előre definiáltak), és a jelenlegi megoldásomat ("category1,category2,category3" stb.) kell átírnom az általatok javasoltra, külön táblákba kiszervezve.
Illetve majd később szeretném a (valódi) lájkolást és kommentelést implementálni, lehet, azt is akkor legalább elő kellene majd készítenem
Köszönöm a sok segítséget, és az időt, amit erre fordítottál! És persze mindenki másnak is a tanácsokat, segítséget.
-
Taci
addikt
Most (utazás után, de még pár hétig nem otthon) volt egy kis időm jobban átolvasni és értelmezni, amit a 3 tábláról írtál. Teljesen jól érthető, köszönöm. Pár részlet még nem világos benne, de azoknak utánajárok.
Illetve 1 dolgot mégis kérdeznék a kódoddal kapcsolatban:
where c.name like '%akármi%'
Ha úgy csinálom, ahogy mondod, és ha 1 terméknek 3 kategória, és így 3 külön rekord a product_category-ban, akkor itt nem kellene már LIKE-ot használnom sem, hiszen rekordonként csak 1 kategória lenne. Szóval ez akkor lehetne inkább:where c.name = 'akármi'
, nem?
(Több kategóriára szűrésnél meg valami ilyemi:where c.name = 'akármi'
or c.name = 'akármi1'
or c.name = 'akármi2'
Javítsatok ki, ha tévedek, kérlek.)És ha jól értem, ugye azt írod, hogy csináljak egy product_category táblát, amibe úgy kerülnének bele a rekordok, hogy ha a fő táblámban (product) mondjuk van 2 millió rekord, és mindegyikhez tartozik 2-4 (átlagban 3) kategória (category). Akkor e szerint a product_category táblában jelen állás szerint 6 millió rekord lenne.
Ez tényleg gyorsabb, mint a 2 milliós? Bár gondolom, erre is írta tm5 a redundanciát (ha nem, kérlek írd meg, mire).
Meg hát ugye azt is írtátok, hogy LIKE-nál az egész adatbázist átnézi, nem számít az indexelés és semmi, szóval az mindenképp lassú.Na ezt nem kis idő lesz így átírnom. Mielőtt nekikezdek: ezt az utat javasoljátok akkor?
- Külön tábla a kategóriáknak.
- Külön tábla a termékek és kategóriák kapcsolatának.
- Lekérdezés előtt (már ahol aktív a kategóriára való szűrés) JOIN.Köszönöm.
-
Taci
addikt
Azt használom, amit a DesktopServer feltelepített nekem: MariaDB. Az alap beállításon van, nem néztem még rá a konfigurációjára. (De utánanézek, hol és hogyan lehet.)
Amit ajánlottatok, külön táblát létrehozni a kategóriáknak, azt egyelőre nem tudom, hogyan kell megcsinálnom, ennek is utánanézek. Illetve akkor lehet, hogy más mezőket is "ki kell majd szerveznem".
Szóval örülnék egy szaki-ajánlásnak.
-
Taci
addikt
Köszönöm a sok és részletes választ, illetve a tippeket!
Nem csak a
LIKE
-os lekérdezésekre ad vissza nagyon lassan választ, de az "alapra" is:SELECT * FROM table ORDER BY date DESC LIMIT 4
Ezért "nem látom, hogy működne" az indexelés, mert se "alap" lekérdezésnél, se kibővítettnél nem gyorsult semmit. Mit tudok még átnézni, változtatni, ellenőrizni? Lehet, csak a lokál szerver "miatt" ilyen lassú? Mert ha más nem, az alap lekérdezésre már jól kellene (gyors válasszal) működnie.----------
(A jelenlegi felépítés szerint) muszáj vagyok LIKE-ot használni:
A kategóriákra szűrök így. Mert jelenleg ha category1, category3 és category4-be tartozik egy elem, az most úgy van letárolva, hogy a category mező tartalma a rekordhoz:"category1,category3,category4"
De a user category1 és category4-re szűr rá, akkor (jelenleg) nem tudom máshogy, mint
AND
(category LIKE '%category1%'
OR category LIKE '%category4%')Rengeteg féle kategória van (30+), így ez lehet egy elég hosszú sztring is, ezért nem is nagyon tudom, hogyan tudnám máshogy megcsinálni.
De ha van tipped, szívesen veszem.Vagy esetleg ezt is lehetne
IN
-nel? Csak nekem úgy kell az eredmény, ha cat1 és cat4-re szűr, akkor mutassa, ha vagy az egyikben, vagy a másikban van (vagy mindkettőben, nyilván). De az IN-nél meg inkább AND az operátor, nem OR.
Tehát aWHERE category IN ('category1', 'category2')
nem jó eredményt adna vissza, nem?Köszönöm.
-
Taci
addikt
Köszönöm a tippet.
Ezt a leírást találtam róla: [link]
Note: Updating a table with indexes takes more time than updating a table without (because the indexes also need an update). So, only create indexes on columns that will be frequently searched against.
Van ilyen lekérdezésem is:
SELECT * FROM table
WHERE channel_id
IN ('id1','id2','id3','id4')
AND
(category LIKE '%category1%'
OR category LIKE '%category2%'
OR category LIKE '%category3%'
OR category LIKE '%category4%'
OR category LIKE '%category5%'
OR category LIKE '%category6%')
AND
(category NOT LIKE '%category7%'
AND category NOT LIKE '%category8%'
AND category NOT LIKE '%category9%')
ORDER BY date DESC LIMIT 4
Ez alapján akkor ezeket a mezőket (channel_id, category) is indexelni kellene, mert végülis ugyanolyan gyakran vannak használva?
Látok a link alatt olyat is, hogy lehet indexet mezők kombinációjára is beállítani. A fenti példám alapján hogy lenne jobb? Index külön a mezőkre? Index ezek kombinációjára? Vagy is-is?És ezt a CREATE INDEX-et csak egyszer kell mezőnként futtatni, és onnan "rendben van"? Azért kérdezem, mert próbálok mindent automatizálni, hogy ne kelljen figyelni rá, ha nem muszáj, és ha ez is olyan, amit többször kell meghívni, akkor erre is figyelnem kell.
Bocsánat a sok kérdésért és értetlenkedésért, csak erről most hallok először, és fontosnak tűnik, nem szeretnék hibázni vele.
Köszönöm.
-
martonx
veterán
Én mint C# fejlesztő, aki mellette sokat SQL-ezett is régen, ezzel nem értek egyet.
Csak szimplán nem kell hülyének lenni, és el kell mélyedni az egyes nyelvekben.
Az SQL totálisan más logikai megközelítést igényel, mint egy normális programnyelv. De mindkettő megérthető, megtanulható.
Több olyan kollégáról is tudok, akiknél nagyon szépen megfér egymás mellett a két világ ismerete, harmonikus használata. -
kw3v865
senior tag
Köszi a választ, megnéztem ezzel a kóddal, de sajnos így az egymást követő sorokban a dátumok között csak 1-2 másodperc a különbség, és hiába állítom az interval értékét 1 percről akár 1000-re, ugyanazokat a dátumokat adja vissza. Kb. ugyanazt az eredményt adja, mint amikor egy egyszerű DISTINCT date-et futtatok a táblára. Legalább is a visszaadott sorok száma azonos.
-
-
martonx
veterán
Előző munkahelyemen a legnagyobb táblában 6 milliárd sor volt, és naponta pár tíz millióval bővült. Ebben csak az volt a pláne, hogy tök sima MSSQL vitte a DB-t egy 32 magos 256Gigabyte memóriás szerveren AWS-ben.
Mondjuk nyilván még ez se volt semmi a telkok DB-ihez képest. -
Ispy
nagyúr
Ha nincsen tele GO-val, akkor még ez sem kell. Simán felül tudod írni a változót a blokkon belül set/select-el.
Csak később vettem észre, hogy GO van az EXEC-ek után, úgy persze, hogy mindig újra kell deklarálni.
Persze jó lenne tudni, hogy pontosan mi a terv, mert így csak kb. találgatunk, hogy most mivan.
-
Taci
addikt
Amire kell csak figyelni: összes a táblába szúró insertnél legyen kitöltve a forrásrendszer azonosító.
Ez alatt ezt érted? (Egy korábbi válasz ugrott be a PHP-s topikból ( [link] ), abban láttam ezt először.)
ENGINE=InnoDB
Ez miért fontos amúgy? Itt amúgy CREATE-nél van. Hol kell/ajánlott ezt használni?
-
Taci
addikt
Köszönöm szépen a sok tanácsot, lesz mit átnéznem/átírnom.
De legalább remélhetőleg stabil kódom/adatbázisom lesz.
Még erre a full-text search-ös dolgot kell majd ránéznem.
Illetve PHP oldalról megnézni, hogy az új struktúrájú lekérdezésben hogyan tudnám hatékonyan használni a
bind_param
-ot. (Ha kell/lehet-e egyáltalán.) -
Taci
addikt
Ha csak 'valami%'-ra alkalmazod a facebook filtert (vagyis ismert a string eleje), akkor legalább a keresendő oszlopra rakott indexből tud dolgozni.
Kereséshez használom, így sajnos nem ismert a sztring eleje, mert a keresett szó bárhol lehet, sor elején, közepén, végén, így muszáj vagyok (jelen ismereteim szerint) így keresni:
LIKE '%szoveg%'
-
Taci
addikt
Ez így valóban jó ötlet. Csak sajnos már mindent a külön táblákra felépítve csináltam meg. De ha azt mondjátok, hogy nagyságrendekkel gyorsabb/hatékonyabb/(nem tudom, mit kellene még itt figyelni) lenne ezzel a szerkezettel, akkor rászánom az időt, és átírom az elejétől kezdve.
Kezdjek neki, vagy azért nincs akkora hátránya az 5 táblából való adatszerzésnek a 1 táblával szemben? Főleg úgy, hogy tényleg csak 4 bejegyzést kérek el egyszerre. (Bár amúgy az 5 tábla a jelenlegi struktúrával fel fog szökni kb. 20 táblára.) -
Taci
addikt
Az 5 táblában 5 különböző forrásból származó bejegyzések vannak, jellemzően több száz (idővel több ezer), ezért vannak már eleve külön táblákba mentve.
És a bejegyzéseket jelenítem meg az oldalon időrendi sorrendben.
Viszont mivel sokszor előfordult, hogy frissült az adatbázis, miközben lapozgattam a listázott bejegyzések között (egyszerre csak 4-et jelenít meg (LIMIT 4, csak azt nem másoltam be a kódrészletbe), aztán görgetés után a következő 4-et, és így tovább), ezért újra ugyanazt a bejegyzést jelenítette meg (mert megjelenítette a 4 legfrissebbet, aztán frissült a bejegyzés, frissebb bejegyzések kerültek előre, tovább görgettem, betöltötte a következő 4-et, de azok egyszer már meg lettek jelenítve a frissítés előtt, így kvázi duplán jelentek meg (nem egymás után, de ha visszagörgettem feljebb, akkor láttam)). Ezért csináltam meg így, hogy amit már egyszer megjelenített, újra nem fogja.Ha fontos az időben csökkenő rendezés, akkor én tennék egy select * from ( ) order by date desc-et az unionok köré.
Itt nekem az a lényeg, hogy az 5 táblából a lapra a bejegyzések időrendi sorrendben kerüljenek. Tehát ha a legfrissebb a table2-ben van, akkor azt jelenítse meg először. Ha a második és harmadik legfrissebb a table4-ben, akkor utána azokat. Lehet, hogy a table1-ben lévő bejegyzések csak a sokadik 4-es csoportban jelennek majd meg, mert annyival régebbi bejegyzések.Logikus teljesen, amit írsz, csak át kell gondolnom, hogy nálam miért jeleníti meg pont úgy, ahogy én akartam - ellenőriztem milliószor az időbélyegzőket is.
Köszi, hogy felhívtad rá a figyelmem, átnézem majd még egyszer.
Tehát ha az első lekérdezést nézem (ahol még nincs kizárva egy ID sem), akkor egy zárójelpár hozzáadása a megoldás, igaz? Így:
(SELECT * FROM table1
UNION ALL
SELECT * FROM table2
UNION ALL
SELECT * FROM table3
UNION ALL
SELECT * FROM table4
UNION ALL
SELECT * FROM table5)
ORDER BY date DESC
LIMIT 4
Legalábbis elvileg, lehet, ez így hibára fut, nem tudom, csak este/holnap tudom majd kipróbálni.
Ez visszaadja a 4 legfrissebb bejegyzést, majd a következő lekérdezés már ennek a 4-nek az ID-jait kizárja, pl. így:
(SELECT * FROM table1
UNION ALL
SELECT * FROM table2
WHERE id NOT IN (1)
UNION ALL
SELECT * FROM table3
UNION ALL
SELECT * FROM table4
WHERE id NOT IN (1,2)
UNION ALL
SELECT * FROM table5
WHERE id NOT IN (1))
ORDER BY date DESC
LIMIT 4
Így lesz a jó?
Köszi.
-
Micsurin
nagyúr
select *
from dba_tables
where table_name='MOTOROK'; és végig próbálgatva is ORA-00942 lesz az az: a tábla vagy a nézet nem létezik.Pedig nulláról kezdtem:
Új kapcsolat Hr-be belépve, létrehoz és feltölt.
Kapcsolódtam a SYS as SYSDBA-ra megadtam az ALL PRIVILEGES-t a Hr-nek.
Létrehoztam a usereket és a role-okat, de semmi változás a dba_tables-re sem lehet lekérdezni. -
Micsurin
nagyúr
hr alól lettek létrehozva a táblák és ott is lett a GRANT kiadva mivel megkötés volt, hogy ne lehessen jogot tovább adni.
De nem akarja az igazságot annyira nem, hogy disconnect majd connect ismét hr-rel átraktam mindent ANY-re, hát nem igazán hatotta meg a dolog mert továbbra sem léteznek a tábláim.
edit.: ezt a DBA-t mindjárt megnézem csak nulláztam a vmwaret inkább berakok minden kódot újra mert kezdtem kuszálni már.
-
Micsurin
nagyúr
Köszönöm!
Életmentő volt holnap lesz csak órai téma de így végre letudom adni a félévest teljesen befejezve és nem kell már vele szórakozzak a héten, legalább ezzel kevesebb!
Keresgéltem de stackover után sem esett le teljesen a dolog pedig tényleg egyszerű...
Érdekes mindig ezekkel az egyszerűbb cuccokkal szenvedek, a tárolj eljárásos, függvényes triggeres téma valahogy jobban feküdt de sanszos, hogy a prog miatt.
-
Micsurin
nagyúr
Akkor jó az elképzelés csak figyeljek a JOIN-ra, nagyon nagyon köszönöm!
Rákérdeztem a demonstrátornál, hogy ebben a formában elfogadható-e erősen kíváncsi leszek és erősen remélem nem ezt a NATURAL JOIN-os formát várják el mert erre nem akar ráállni az agyam nem logikus nekem az ALIAS-ok is hiányoznak.
Az ALIAS-ok elhagyására érted, hogy átláthatóbbá teszik?
Majdnem olyan rossz a hiányuk számomra mint a #MyRegion elhagyása C#-ban és az ömlesztett kódot bámulni. -
Micsurin
nagyúr
Hatalmas köszönet a két válaszért! El sem tudod képzelni milyen nagyon sokat segítettél vele!
Az az SQL*PLUS mikor megláttam azt hittem kiugrok a bugyiból ijedtemben.
Rögtön felötlöttek bennem a linuxos élmények a szóközökkel kapcsolatban és a szép gondolatok, hogy itt hagyom ezt az egészet a f*ba azt mehet egy motorszerelői OKJ.
Ez van ezt kell szeretni és túlélni szerencsére csak ez az 1 adatos tárgyam van/lesz.(mert nincs az az isten, hogy én BigData-ra menjek hamarabb megyek el szoftverre, pedig hálózat vagy beágyazott rendszerekre akarok célozni.
)
-
Micsurin
nagyúr
Wow jogos, köszönöm ezt felvésem jól jön ez még a beágyazottaknál.
Nem opcionális a használata meglett mondva 3db GROUP + HAVING lekérdezés akkor azt így kell... valamit beleszuszakolok még ebbe és jó lesz nem értelmes kell legyen mint megoldása egy problémának csak szintaktikailag jónak.
-
nyunyu
félisten
-
bambano
titán
úgy kezdted a megoldásodat, hogy csináljon másolatot a tábláról.
ez már önmagában zűrök okozására ad lehetőséget.
ha például jávába beolvasod az adatokat, feltéve, hogy beférnek, akkor is ott lesz a probléma, hogy a riport futtatása közben vásárolnak, és akkor szétszalad a valós raktárkészlet adata meg a temp tábla adata."minden egyes lépés kiértékelésénél a DBnek egyesével újra kell számolnia az eddigi lépések eredményét": ez tény, de feladattól, környezettől függ, hogy ez hátrány vagy előny.
nekem az a véleményem, hogy hagyni kell az adatbáziskezelőt dolgozni.
az, hogy a bi ócska, az másvalaki problémájavegyenek bele több ramot.
-
martonx
veterán
Bocs, pontatlan voltam. Az SQL-t nem számítom a programnyelvek közé. De igazad van végülis ez is programnyelv, csak épp nem imperatív. Ugyanígy nem tekintem programnyelvnek a CSS-t sem
Legalábbis a magam pongyola megfogalmazásában.
A Java lambdát ne keverd ide, az csak egy syntetic sugar, nem attól lesz deklaratív nyelv a Java. De kezdünk nagyon eltérni az eredeti problémától
-
martonx
veterán
"Ettől még fenntartom azt, hogy Javaban egyszerűbb lenne lekódolni+gyorsabban is futna."
Mármint bármilyen programnyelven (javascript, php, c#, python, java, stb...) és nem csak egyszerűbb lenne lekódolni, és nem csak gyorsabban is futna, de könnyedén debuggolható, logolható, verzió kezelhető is lenne.
Noha mindezt SQL-el is meg lehet oldani, de elképesztően nyögve nyelősen. -
mr.nagy
tag
Köszönöm a választ, de a példánál maradva nincs központi raktár és sajnos a kereskedők az üzletben olyanok amilyen. Nem lehet rájuk bízni ezt a kérdést.
Esetleg két ideiglenes tábla, az egyikbe írom a kiegyenlítést a másikba csökkentem ennyivel az értéket, majd a második alapján új ciklus. Ez a ciklus addig fut, míg van hova tenni?
-
tm5
tag
Én is valami hasonlóra jutottam, mint nyunyu, hogy ehhez minimum egy tárolt eljárás szükséges, ezt 1 sql paranccsal nagyon nem lenne egyszerű megoldani.
Valami olyasmit csinálnék, hogy generálnék 2 listát (plusz(i): pozitívok csökkenő sorrendben, minusz(j): negatívok növekvő sorrendben) és mennék végig a minusz listán úgy, hogy a plusz-os lista aktuális elemével megpróbálnám kiegyenlíteni a negatív értéket. ha nem tudom, akkor nézem a következőt a minuszból. Addig megy a ciklus, amíg a végére nem érsz valamelyik listának. + eköré még kellene még egy loop ami az elején újraszámolja a plusz, minusz listákat és addig megy amíg vannak update-ek. Valami ilyesmi lenne... -
DeFranco
nagyúr
köszönöm, akkor már az elv sem volt jó, akkor így már világos.
gondolom akkor ezt azzal tudom áthidalni hogy előre with-elek mindent amit egyébként subquerybe raknék, majd onnan szedem be a megfelelő mutatókat egy fő querybe.
amint lesz lehetőségem átrendezem így a lekérdezést.
-
DeFranco
nagyúr
nos...
az oldschool módszert használom, ahogy írod és szépen megy is addig, ameddig leírtad.
ezek ugye önmagukban (a zárójelek között) önálló selectek, egymás változóit nem használják csak egymás mögé vannak láncolva.
(az hogy pivotolgatok is ezekben az önálló selectekben, az egy másik kérdés. szerintem redundáns és ki kellene szedni de még nem jöttem rá a mikéntjére, ha csak simán kiszedem akkor az egy-a-többhöz kapcsolatok miatt a 20k-s valós rekordszámból a várt 400k-s rekordszám helyett (x20 oszlop a pivotban) 380 millió rekord lesz, nyilván én vétek hibát valahol)
ez alá jönne az a rész (amit én írtam lentebb) amikor az önálló, tábla-szerű egységgé zárójelezett, aliasolt blokkokból ki szeretnék venni mutatókat, azokat pl. összeszorozni vagy kivonni, és ez már nem megy. mutatom példában:
SELECT * FROM
(
SELECT
AL1.munkavallalo...
FROM... AL1
) K
JOIN
(
SELECT
AL2.munkavallalo
AL2.mutatoX
FROM AL2
) KHD
ON K.munkavallalo = KH.munkavallalo
JOIN
(
SELECT
AL3.munkavallalo
AL3.mutatoY
FROM AL3
) AHD
-- eddig a te logikáddal megegyezik, annyiban tér el hogy select * from van a definiált értékek helyett, de ez indifferens azt hiszem
-- innen jönne az amit én szeretnék, de nem megy
JOIN
(
SELECT
K.munkavallalo
KHD.mutatoX-AHD.mutatY
FROM
???
) KAMEHAMEAde azt hiszem az első opció szerint lenne elegáns megcsinálni, én is gondoltam már erre (mióta megtanultam Tőled a where-t
) valószínűleg az lenne a praktikus.
-
nyunyu
félisten
FROM (select munkavallalo, ...
from ...
where ...) K
JOIN (select munkavallalo, ...
from ...
where ...) KHD
ON KHD.munkavallalo = K.munkavallaloErre gondoltam múltkor, amikor azt írtam, hogy tetszőleges select köré lehet zárójelet tenni, és az alquery mögéírt aliasnevet táblaként használni, ahol az SQL szintaxisa táblanevet vár.
Csak a korábbi példánál még nem értettem, hogy mit akarsz joinolni hova.
-
DeFranco
nagyúr
igen csak itt az általad leírt selectben már eleve aliasolt selectek a "táblaazonosítók" (K, KHD, KH, AHD)
és mivel a SELECT szintaktikája ha jól tudom megköveteli a FROM-ot, nem tudom mit írhatnék a ??? helyére, mert ha azt írom hogy
SELECT
K.[munkavállaló] "MUNK"
KHD.[érték]/AHD.[érték] AS "KPERA"
KH.[hónapazonosító] AS "HO"
FROM
K
JOIN KHD
ON
K.valami = KHD.valami
JOIN KH
ON
K.valami = KH.valami
JOIN AHD
ON
K.valami = AHD.valamiakkor az nem működik. azt nem tudom hogy elvileg kellene-e működnie, sajnos favágó módszerrel tanulom az sql-t
-
DeFranco
nagyúr
köszönöm szépen, így sem működött de megoldottam, egyszerűen kiszámoltattam vele még a selectben és azt pivotoltattam az abszolút érték helyett
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,
t.ertek/o.osszeg arany
from tabla t
join egyed_osszeg o
on t.egyed_azonosito = o.egyed_azonosito
)
pivot
( sum(arany)
for csoport_kepzo in ('A','B'...)
)így már szépen működik, elé joinoltam az abszolút értékeket és teljes lett a tábla
köszönöm még egyszer a tippeket
-
DeFranco
nagyúr
Köszönöm szépen, nagyjából működik de nem teljesen:
1: a sum(ertek)/osszegre ugrik az ellenőrzés, nem fut le, a hibaüzenet az alábbi:
ORA-56902: összesítő függvényt várható a forgatási műveletben
56902. 0000 - "expect aggregate function inside pivot operation"
*Cause: Attempted to use non-aggregate expression inside pivot operation.
*Action: Use aggregate function.2: ez csak nekem kérdés mert még nem vagyok otthon pivotban: ha sum(ertek)-en hagyom tehát nem képzek indexet, akkor az eredménytábla úgy néz ki hogy ezeket az oszlopokat pakolja egymás mellé:
egyedi_azonosito II o.osszeg II A II B II C II stb.
tehát az [o.osszeg] oszlopot a pivotolt résztől függetlenül beteszi a "sorfej" és az "oszlopok" közé
Ez azért van, mert a pivotnál mindent sorfejlécnek értelmezünk ami nincs benne a sum és a for mezőkben és az a lekérdezés sorrendje szerinti hierarchiában alábontást jelent?
-
-
-
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; -
Louro
őstag
Igazán "minőségi" megoldás az lett volna, ha készül egy dictionary arra, hogy táblanév-oszlopnév-oracle táblanév-oracle oszlopnév
A szabványok jók és hasznosak, de azért néha nem árt frissíteni azokat.
@Szmeby: Szerintem a beszállítókat nem hibáztathatjuk, mert lehet elhangzottak ellenérvek. De a megrendelőnek/ügyfélnek mindig igaza van. Az se igaz, hogy minőségi cég nem végez kontár munkát. Van az a pénz.
Nálunk - pénzintézet - szintén az évek az alatt olyan igények születtek, hogy már csoda, hogy működik a rendszer. Mindig kértek valamit. Félig leszállították, mert gyorsan kellett valami. De a végét már nem rendelték meg, mert addig volt rá működő workflow. És az igények is olyanok .... . Régiek közül persze már szinte senki sincs. Szóval, ha kérdés merül fel, szép kutató munka.
-
Szmeby
tag
És gondolom, a projektben résztvevő összes cég azt állítja magáról, hogy csak minőségi szoftvert adnak ki a kezükből, a szakmai kiválóság az elsődleges.
Szerintem amúgy nem szar a terv, csak a tervező bizonyára elfelejtette, hogy a munkája nem ér véget a Generate gomb megnyomásával. A többi résztvevő meg nem volt elég tökös visszadobni a félkész produktumot. Pénz van, idő nincs, nyilván a gányolás felé húz ezek után minden résztvevő szíve. Nem szar ez, hanem kihívásokkal tűzdelt. Azt meg minden fejlesztő szereti, sokan a cv-be is beírják, a kihívás fontos.
(Sosem értettem, miért nem illik megosztani a nyilvánvaló ostobaságokat elkövető (jogi) személyek / projektek nevét. Mások okulására és tájékoztatására, hogy "ide ne gyertek dolgozni, ha nem akartok inkompetens, egyeztetésre képtelen egyedekkel együtt dolgozni". Mindig csak a cukormáz látszik. Pedig hibázni jó dolog, de azt nem beismerni totális káoszba vezet. És kinek van kedve káoszban létezni? Habár biztos akad olyan is, de én nem tartozom közéjük.)
-
nyunyu
félisten
Közben találtam egy másik megoldást, ami nem a JOINnál szűr, hanem CASE WHEN-ekkel pakolja külön oszlopokba az egyes tételeket:
SELECT p.projectName 'Project Name',
SUM(CASE WHEN pc.costCategory='Cost category1' THEN pc.cost ELSE 0 END) 'Cost category1',
SUM(CASE WHEN pc.costCategory='Cost category2' THEN pc.cost ELSE 0 END) 'Cost category2',
SUM(CASE WHEN pc.costCategory='Cost category3' THEN pc.cost ELSE 0 END) 'Cost category3',
SUM(CASE WHEN pc.costCategory='Cost category4' THEN pc.cost ELSE 0 END) 'Cost category4'
FROM Project p
LEFT JOIN ProjectCost pc
ON pc.projectID=p.projectID
GROUP BY p.projectName
ORDER BY p.projectName;De ez sem sokkal olvashatóbb
Jut eszembe, hasonló példával szívatott a mostani főnököm 3 éve állásinterjún.
Aztán nemsokkal később belebotlottam kolléga kódjába, ami 10 attribútum nevét és értékét feszíti ki egy termék sorra ugyanígy
Azóta sem mertem átírni PIVOTra. -
bpx
őstag
Ezek az Oracle saját tanfolyamai. Mindenhol ennyi lesz az ára nagyságrendileg és a tananyag is ugyanaz lesz. Az Oracle Hungary az oktatási részlegét leépítette, az oktatási partnerek tartják nekik a tanfolyamokat.
Több helyen is vannak egyedileg egyeztetett tematikájú ás formátumú oktatások is. Ezek ár/értékben kedvezőbbek. Talán.
De igazából egyik változattal sem vagyok megelégedve.
Az említett Webváltónál dolgozom, 10 éve. Nem foglalkozom oktatással, csak ha nagyon muszáj.
-
Louro
őstag
Én is mellőzöm a right join-t, mert az agyunk balról jobbra értelmez. De, amikor mondja, hogy mi a feladat és hogyan kezdet neki, akkor ott volt,hogy right kellett volna. Amikor nagyon junior voltam, szégyeltem volna olyan kérdéseket feltenni, mint amiket én kapok manapság.
A senior-nak is már ajánlottam az sqlzoo.net oldalt és tegnap találtam az Oracle oldalán is egy tök jó leírást kezdőknek, ahol elég sok példa mentén van elmagyarázva.
Kicsit ON is legyek. Már 8 éve SQL-ezek. Bár nem tartom magam veteránnak kódismeret szintjén, de 5 év Oracle és most 3 év T-SQL a hátam mögött kicsit tovább lépnék. DBA irány szimpatikus. Van olyan iskola, ami különösen ajánlott vagy nagyon kerülendő?
-
bpx
őstag
Konstans értéket nem kell a group by-ban felsorolni.
De, tud alias alapján rendezni.
Nem, nem tud oszlopszám szerint csoportosítani.select
1 + 2 as harom,
null as ertek2,
created as letrehozva,
sum(user_id) as valami,
count(*) as darab,
'hello' as ertek3
from
dba_users
group by
created
order by
harom,
letrehozva
;
HAROM E LETREHOZVA VALAMI DARAB ERTEK
---------- - ------------------- ---------- ---------- -----
3 2020-04-16 19:04:45 6442450869 6 hello
3 2020-04-16 19:04:46 13 1 hello
3 2020-04-16 19:06:12 43 2 hello
3 2020-04-16 19:06:18 23 1 hello
3 2020-04-16 19:07:31 2147483638 1 hello
3 2020-04-16 19:08:08 36 1 hello
3 2020-04-16 19:15:29 48 1 hello
3 2020-04-16 19:15:31 49 1 hello
3 2020-04-16 19:15:37 101 2 hello
3 2020-04-16 19:18:29 61 1 hello
3 2020-04-16 19:18:41 62 1 hello
3 2020-04-16 19:20:21 70 1 hello
3 2020-04-20 20:51:53 73 1 hello -
nyunyu
félisten
Jut eszembe, ezt is lehetne egyszerűbben írni:
SELECT
y.nev,
MAX(ar) max_ar
FROM t_cikk x
INNER JOIN t_tarsasjatek y
ON x.tarsasjatek_id = y.id
GROUP BY y.nev
ORDER BY MAX(ar) DESC;De amennyire emlékszem Oracle nem nagyon szokta szeretni, ha számolt oszlopokra próbál rendezni az ember, sokszor kaptam hasonló próbálkozásokra szintaktikai hibát, emiatt írtam inkább köré egy másik selectet a rendezéssel.
Más adatbáziskezelők rugalmasabbak ebben.
Új hozzászólás Aktív témák
Hirdetés
- Norvégia átmenetileg betiltja az áramigényes kriptobányászatot
- Beszántaná a marketingért felelős részlegét az Intel
- Windows 10
- One otthoni szolgáltatások (TV, internet, telefon)
- LEGO klub
- Milyen videókártyát?
- VR topik
- Abarth, Alfa Romeo, Fiat, Lancia topik
- Motorola Edge 50 Neo - az egyensúly gyengesége
- BMW topik
- További aktív témák...
- AKCIÓ! ASUS MAXIMUS VIII HERO Z170 chipset alaplap garanciával hibátlan működéssel
- Bomba ár HP X360 11 G5 - Intel 4020 I 4GB I 128GB SSD I 11,6" HD Touch I Cam I W11 I Garancia!
- Telefon felvásárlás!! iPhone 12 Mini/iPhone 12/iPhone 12 Pro/iPhone 12 Pro Max
- AKCIÓ! VALVE INDEX virtuális valóság szemüveg garanciával hibátlan működéssel
- HPE Apollo 4200 Gen9 2U rack szerver, 1x E5-2620v4, 64GB RAM, 24x3.5" 2U-ban! ÁFA-s számla, garancia
Állásajánlatok
Cég: Promenade Publishing House Kft.
Város: Budapest
Cég: PC Trade Systems Kft.
Város: Szeged