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

(#5151) tm5 válasza bambano (#5150) üzenetére


tm5
tag

SELECT TRUNC(datum) AS nap,
       CASE WHEN DATEPART(HOUR,datum)>11 THEN 'DU' ELSE 'DE' END AS napszak,
       SUM(szam) AS osszeg 
   FROM tabla
GROUP BY nap,
CASE WHEN DATEPART(HOUR,datum)>11 THEN 'DU' ELSE 'DE' END
ORDER BY 1,2

Legyen neked Karácsony Nálunk 12 és 1 között ebéd szünet van, olyan senkiföldje.

(#5152) bambano válasza tm5 (#5151) üzenetére


bambano
titán

minek két case? :)

Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis

(#5153) Pulsar válasza tm5 (#5149) üzenetére


Pulsar
veterán

Hu, köszi. Azt elfelejtettem mondani, hogy reggel 6kor kezdődik az első 12 óra, és 18h-kor a második és tart másnap reggelig :)

(#5154) Ispy válasza Pulsar (#5153) üzenetére


Ispy
veterán

Azért egy case-t megírni nem rakétatudomány, módosítod a feltételt, ahogy akarod. :)

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

(#5155) tm5 válasza bambano (#5152) üzenetére


tm5
tag

Az egyikkel a shiftet nyomom, de amúgy megmutatnád 1 case-zel, please?

(#5156) bambano válasza tm5 (#5155) üzenetére


bambano
titán

select akarmi as nap,
     case when date_part('hour',datum)<18 and date_part('hour',datum)>5
                 then 'DE' else 'DU' end as műszak
from tabla group by 1,2 order by 1,2;

Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis

(#5157) tm5 válasza bambano (#5156) üzenetére


tm5
tag

Jé, azt nem tudtam, hogy a group by-nál is lehet számokat használni...

(#5158) bambano válasza tm5 (#5157) üzenetére


bambano
titán

azt leírtad, hogy valami as nap és után a group by nap, de azt nem, hogy valami as összeg és group by összeg? :) :P

Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis

(#5159) sztanozs válasza bambano (#5156) üzenetére


sztanozs
veterán

Ez viszont nem jól fogja számolni, lesz egy nap két DE (2*8 óra, hajnalban és éjszaka) és egy DU (1*16 óra napközben).

Valahogy így lehet jó:
SELECT
TRUNC(dateadd(hour,-8,datum)) AS nap,
CASE WHEN date_part('hour',dateadd(hour,-8,datum))>12 THEN 'DU' ELSE 'DE' END AS muszak,
SUM(szam)
FROM tabla
GROUP BY 1,2 ORDER BY 1,2;

Így a hajnal még az előző naphoz fog tartozni mint DU műszak.

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...

(#5160) tm5 válasza bambano (#5158) üzenetére


tm5
tag

Jaja a nap a group by-ban az hiba, látom így utólag, csak ugye így éjfél felé már ennyi belefér. Majd szól a fordító.
De azt tényleg nem tudtam, vagy soha nem próbáltam oszlopszámmal a group by-t. Ennyi...de hála neked most már ezt is tudom :)

(#5161) bambano válasza sztanozs (#5159) üzenetére


bambano
titán

ez matematikailag jó, de én nem használnám az érthetősége miatt... inkább:

date_part('hour',datum) between 8 and 16 then 'DE' else 'DU' end

Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis

(#5162) sztanozs válasza bambano (#5161) üzenetére


sztanozs
veterán

Jaja, viszont a tiéd matematikailag helytelen: az egybe nem tartozó ‘délelőtti’ értékeket kumulálja (az előző második műszak végét, a következő második műszak elejével).

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...

(#5163) bambano válasza sztanozs (#5162) üzenetére


bambano
titán

:R

Egy átlagos héten négy hétfő és egy péntek van (C) Diabolis

(#5164) Taci válasza sztanozs (#5140) üzenetére


Taci
addikt

Ha az általad írt lekérdezés által visszaadott össz-elemszámot szeretném megtudni (a belső limit nélkül - hogy később tudjak vele számolni, a belső limit meddig nyújtózkodhat - szóval a belső Select-et ezért veszem ki, plusz ugye nem kell rendezni sem (Order By), és a végén lévő Limit sem kell)), akkor jelen tudásom szerint azt így kérdezném:

SELECT COUNT(*) AS result_count FROM
(SELECT i.item_id FROM items AS i 
INNER JOIN items_categories AS c ON i.item_id=c.item_id
WHERE 
  c.category_id NOT IN (1,3,13,7,20) AND
  i.item_id NOT IN (117,132,145,209,211)
GROUP BY i.item_id) AS t

Van esetleg ennek hatékonyabb, gyorsabb, jobb módja?

Ezt találtam még:
SELECT COUNT(DISTINCT item_id) AS result_count FROM
(SELECT i.item_id FROM items AS i
INNER JOIN items_categories AS c ON i.item_id=c.item_id
WHERE
c.category_id NOT IN (1,3,13,7,20) AND
i.item_id NOT IN (117,132,145,209,211)) AS t

Itt elvileg a Distinct kiváltja a Group By-t.

Viszont sajnos Count-hoz a phpMyAdmin nem ír lekérdezési időt, így nem tudom, melyik a gyorsabb. Vagy jobb.

Ebben kérnék tanácsot.
Köszönöm.

(#5165) Taci


Taci
addikt

Illetve még azt kérdezném külön témaként, elméleti kérdésként:

Eddig úgy csináltam, hogy kértem 4 elemet (query, Limit 4), a kliens felhasználta, kért újabb 4 elemet, felhasználta és így tovább.
Tehát 4 elemenként volt egy query az adatbázisból. Per kliens.
Ez azért volt jó (inkább kényelmes), mert abban a pillanatban, hogy nem 4 elemet kapott a kliens vissza, megvolt, hogy nincs több elem, jöhet a no_more_items elem.

Most azt nézem, hogy a Limit 64-gyel egyből betöltök 64 elemet. Ez nyilván 16-szor több (szöveges) adatot jelent egyben, viszont így is csak kb. 30 kB a Limit 4-nek a kb. 2 kB-jával szemben. 30 kB-nyi adat pedig semmi, és ezzel a query-k számát is drasztikusan leredukálhatom. (4 elemenkéti lekérdezés helyett csak 64 elemenkénti).

Viszont ezzel egy teljes szerkezeti változást meg kell csinálnom a PHP és a JS fájljaimban is. Amit persze szó nélkül megteszek, csak szeretnék előbb tanácsot kérni, hogy melyik a jobb út. Vagy van-e egy harmadik út, ami még jobb lenne.

Ha a szervernek "nem fáj" az ilyen sűrű lekérdezés (és nem is lassítja - több ezer felhasználó egyidejű lekérdezéseit figyelembe véve sem), akkor maradok a Limit 4-nél.

De ha ez a sűrű lekérdezgetés rossz hatással van a válaszidőre, és ezzel a felhasználói élményre is, akkor nézegetem a másik utat, hogy egyszerre több adatot kérek le, és az utolsó pár elemig azzal eldolgozgat a kliens lokálban, aztán a vége felé kéri az újabb adagot.

Vagy van valami más, jobb út?

Köszönöm.

(#5166) pch


pch
aktív tag

-- delete --

[ Szerkesztve ]

http://sb-soft.hu - "A" számlázó

(#5167) Taci válasza pch (#5166) üzenetére


Taci
addikt

Sosem találkoztam még vele, úgyhogy ránéztem. És itt azt taglalják, hogy az SQL_CALC_FOUND_ROWS általában véve lassabb, mint a két külön query (az eredeti + a count).
Plusz ahogy olvasom, a jövőbeli verziókból már ki is szedik a támogatottságát:
The SQL_CALC_FOUND_ROWS query modifier and accompanying FOUND_ROWS() function are deprecated as of MySQL 8.0.17 and will be removed in a future MySQL version.
És hogy a COUNT(*)-ot ajánlják helyette.

Köszönöm azért a tippet, legalább láttam, hogy ilyen is van (lassan: volt).

(#5168) pch válasza Taci (#5167) üzenetére


pch
aktív tag

Közbe énis olvastam, hogy kivezetik ezért töröltem, de látom megelőztél :)

http://sb-soft.hu - "A" számlázó

(#5169) sztanozs válasza Taci (#5164) üzenetére


sztanozs
veterán

Nem kell belső select, csak ennyi:
SELECT COUNT(*)
FROM items AS i INNER JOIN items_categories AS c ON i.item_id=c.item_id
WHERE
c.category_id NOT IN (1,3,13,7,20) AND
i.item_id NOT IN (117,132,145,209,211)
GROUP BY i.item_id, i.item_date

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...

(#5170) Taci válasza sztanozs (#5169) üzenetére


Taci
addikt

Így nem ugyanazt az eredményt kapom vissza.

Az én változatommal:
result_count
299660

A tiéddel:
COUNT(*)
1
3
2
3
3
3
3
2
3
3
3
2
stb.

De a lényeg akkor gondolom az, hogy a COUNT(*)-os megoldás a jó (jobb).

(#5171) Taci


Taci
addikt

Lehet, triviális a válasz, de:

Egy Count-lekérdezés végrehajtása ugyanannyiba kerül, mint pont ugyanannak a query-nek a Count nélküli változata?

Azért merült fel a kérdés, mert ha a Count nélkülivel eleve megkapom magukat az elemeket is, akkor ha csak a Count-ban tér el a két query, abban az esetben nincs értelme a Count-ot használni, hisz' az csak az elemek számát adja vissza, míg a másikkal megkapom az elemeket is, amiket aztán meg összeszámoltatok egyszerűen.

(Nyilván lehet millióféleképpen használni, én sem csak így használom, de amikor pont ilyen eset lenne, hogy a Count-on kívül minden más ugyanaz, akkor vajon ugyanannyi időt vesz igénybe mindkét lekérdezés? Tippem szerint igen, hisz' ugyanúgy kell elvégezni minden műveletet benne, így a Count csak összeszámolja az eredménytáblát "és kész".

De most már inkább rákérdezek.)

(#5172) nyunyu válasza Taci (#5171) üzenetére


nyunyu
félisten

Azt ne felejtsd ki a képletből, hogy a count() lekérdezésnek a végeredménye egy szám, míg a count() nélkülié egy adathalmaz, aminek a DB szerverről letöltése lényegesen tovább tart.

Tegnap kellett lementenem egy 850k soros táblához kapcsolódó adatokat CSVbe, eltartott vagy 20 percig, mire lejött a 160 mega adat a céges VPNről.
Ugyanez select count(*) from (eredeti query)-vel 5 másodpercig tart.

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

(#5173) Taci válasza nyunyu (#5172) üzenetére


Taci
addikt

Hmm, erre nem is gondoltam. Milyen jól tettem, hogy feltettem a kérdést. :)
Köszönöm! :)

(#5174) nyunyu


nyunyu
félisten

Jééé, Oracle 19c alatt már működik az oszlop aliasra order by, és nem kell kiírni az egész képletet? :Y

11 csak oszlopszámra, vagy komplett képletre engedett order by-olni.

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

(#5187) pch


pch
aktív tag

Ha már mysql lenne egy kérdésem :D
Van egy tábla amibe a dátumok vannak (meg egyéb adatok, de ez most nem lényeg)
Van egy másik tábla amibe egy adott dátumhoz hozzá van fűzve egy érték.
Meg van egy harmadik tábla amibe van egy kezdőérték.
Melyik az a számolási metódus amivel a kezdőértékhez ha hozzáadom a dátumnál letárolt értéket az lesz a következő kezdőérték, és ha talál egy későbbi dátum<>értéket azt az előzőhöz adja hozzá?
php alatt ugye a x=x+y
Azaz egyik táblába vannak mondjuk a hónap-napok egymás után (2021-08-01 ... 2021-08-31)
Másik tábla (2021-08-20 1500) (2021-08-23 3500)
A harmadik táblába az induló 5000
Akkor ezt szeretném kapni:
2021-08-01 től 2021-08-19 ig 5000,
utána 6500
majd 23-tól 10000
Köszönöm!

http://sb-soft.hu - "A" számlázó

(#5199) Taci


Taci
addikt

Adott ugyanaz a témakör, ami korábban is.
A kérdésem a következő lenne:

Adott példának okáért ez a lekérdezés: DB Fiddle

Itt ami fontos lenne nekem, hogy ha egy kategóriára azt mondom, hogy nem érdekel (category_id not in (27)), akkor azokat az elemeket ne jelenítse meg, amikhez ez a kategória hozzá van rendelve. (Pl. ha azt mondom, allergiás vagyok a mogyoróra, akkor ne mutasson olyan recepteket, amiben mogyoró van)

Ezzel az adott lekérdezéssel viszont nem így működik.
Direkt úgy módosítottam a példát, hogy könnyen látni lehessen:

INSERT INTO `items_categories` (`id`, `item_id`, `category_id`) VALUES
(349, 117, 27),
(350, 117, 26),
(351, 117, 29)

Tehát 117-es elem benne van a 27-es, 26-os és a 29-es kategóriában.

Ha én azt kérem, hogy azokat az elemeket ne jelenítse meg, amik a 27-es kategóriába tartoznak (category_id not in (27)), azt várnám, hogy a 117-es elemet nem jeleníti meg egyáltalán.

Viszont ebben a formájában ez nem így működik, mert ezzel csak azt érem el, hogy eredménybe visszaadja a 117-est is, mert a 3 rekordból kizárja azt az egyet, ami a 27-es kategóriás, viszont a maradék kettő miatt a találati listában marad.

Hogyan lehet megoldani ezt?

Köszönöm.

(#5200) Sokimm


Sokimm
senior tag

Sziasztok!
A MsAccess fórum elég kihaltnak tűnik, ezért itt tenném fel a kérdésem:
Van egy gyermektábor, amiben 3 tábla adja az adatbázist.
Az első tábla, a gyerekek neve, szülők kapcsolattartó elérhetősége, extra adatai vannak.
A második tábla, a gyerekek egyedi táboros igényeit taglalja (vega, hány napot van, melyik foglalkozás érdekli, stb).
A 3. táblába szeretném a gyerekek információs táblájából kinyerni CSAK a nevüket, és mellé a második tábla opciós mátrixát dinamikusan hozzáilleszteni. (táborba érkezés regisztrációkor név: mit kér enni, mire jött, stb)
A problémám az, hogy míg az adatok lookup table szerű dinamikus változói szépen létrejönnek, addig a gyerekeket egyesével kell a rekordok közé felvenni, és rohadt fárasztó 100 gyereknél. :) Van rá valami mód, hogy a recordokat autofill módon feltöltse az első táblából?
Később jöhet még 1-1 gyerek, azokat már manuálisan hozzáadnám a 3. táblához, de a tömeget nem szeretném egyesével.
Ha ez túl Microsoft-os téma (szintaktika acces szinten), akkor kérlek ne haragudjatok, viszont ha szemantikailag (lehetetlen teljes adattáblákból oszlopok "copy"-ja másik táblában adatbáziskezelő programokban) vagyok lemaradva, kérlek világosítsatok fel, miként oldanátok meg a problémám.
A válaszokat előre is köszi.

Útvonal

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