Pre mňa asi príliš zložitý SELECT v MySQL

Pre mňa asi príliš zložitý SELECT v MySQL
« kdy: 26. 01. 2015, 22:11:42 »
Mám tabuľku, v ktorej mám niekoľko tisíc položiek. Každá položka v jednom období obsahuje niekoľko rôznych údajov. Dvojica (`date`,`kod`) je jednoznačný údaj a je to aj primárny index. V ďalších stĺpcoch tabuľky sú tie údaje. Sú platné vždy od konkrétneho dátumu až do ďalšej zmeny. Zmena sa zapíše s rovnakým kódom a aktuálnym dátumom do ďalšieho riadku. Údaje sa nemenia všetky v rovnakom čase. Keď chcem nájsť platné údaje k určitému dátumu, tak potrebujem vrátiť riadok s najbližším starším dátum ako hľadám.
Keď chcem nájsť jednu položku platnú v určitom momente, je to celkom jednoduché:
Kód: [Vybrat]
SELECT * FROM `table` WHERE `date` < (požadovaný dátum) AND `kod` = (žiadaný kód) ORDER BY `date` DESC LIMIT 1Ako však napíšem select, ktorý mi vyberie všetky platné riadky? T.j. vráti mi všetky riadky s kódmi (pre každý kód jeden riadok), pre ktorý existuje riadok s dátumom starším ako požadujem?
Skúšal som všeličo, ale buď výpočet trval príliš dlho alebo som dostal nezmysly.
« Poslední změna: 27. 01. 2015, 08:45:21 od Petr Krčmář »


Lemming

Re:Pre mňa asi príliš zložitý SELECT v MySql
« Odpověď #1 kdy: 26. 01. 2015, 22:30:27 »
Zkus něco jako:

select * from table t where t.kod=sq.kod and t.date=sq.date
(select `kod`,max(`date`) as `date` from table where `date` < (datum) group by `kod`) sq;

Výkonu by mohlo pomoct když v indexu budou sloupečky v pořadí kód a pak datum (ne opačně).

ps

Re:Pre mňa asi príliš zložitý SELECT v MySql
« Odpověď #2 kdy: 26. 01. 2015, 22:44:17 »
Ak môžeš navrhni si tabuľku takto
Kód: [Vybrat]
MyTable (myid INT, validFrom DATE, validTo DATE, ...)
Keď budeš mať zmenu tak spravíš
Kód: [Vybrat]
BEGIN TRANSACTION
UPDATE MyTable SET validTo=now() Where myid = <changed_id> and validTo is NULL
INSERT INTO MyTable (myid, validFrom, validTo, ...) values (<changed_id>,now(),NULL,...)
COMMIT TRANSACTION

Keď chceš iba platné záznamy, tak
Kód: [Vybrat]
SELECT * FROM MyTable WHERE validTo is NULL ... [code]

Skús porozmýšlať nad výhodami a nevýhodami tohto a tvojho prístupu. Niečo sa možno dočítaš aj tu: http://saphanatutorial.com/sap-hana-history-table/

Re:Pre mňa asi príliš zložitý SELECT v MySql
« Odpověď #3 kdy: 26. 01. 2015, 22:57:07 »
Zkus něco jako:

select * from table t where t.kod=sq.kod and t.date=sq.date
(select `kod`,max(`date`) as `date` from table where `date` < (datum) group by `kod`) sq;

Výkonu by mohlo pomoct když v indexu budou sloupečky v pořadí kód a pak datum (ne opačně).
Nakoniec som to napísal takto:
Kód: [Vybrat]
select * from table t
JOIN (select `kod`,max(`date`) as `date` from table where `date` < (datum) group by `kod`) sq
ON t.kod=sq.kod and t.date=sq.date
Tých údajov zas nie je až tak veľa (<10000) a menia sa nie príliš často, rádovo v mesiacoch, takže rýchlosť je výborná, ďakujem za nakopnutie.

Re:Pre mňa asi príliš zložitý SELECT v MySql
« Odpověď #4 kdy: 26. 01. 2015, 22:59:36 »
Ak môžeš navrhni si tabuľku takto
Kód: [Vybrat]
MyTable (myid INT, validFrom DATE, validTo DATE, ...)
Keď budeš mať zmenu tak spravíš
Kód: [Vybrat]
BEGIN TRANSACTION
UPDATE MyTable SET validTo=now() Where myid = <changed_id> and validTo is NULL
INSERT INTO MyTable (myid, validFrom, validTo, ...) values (<changed_id>,now(),NULL,...)
COMMIT TRANSACTION

Keď chceš iba platné záznamy, tak
Kód: [Vybrat]
SELECT * FROM MyTable WHERE validTo is NULL ... [code]

Skús porozmýšlať nad výhodami a nevýhodami tohto a tvojho prístupu. Niečo sa možno dočítaš aj tu: [url=http://saphanatutorial.com/sap-hana-history-table/]http://saphanatutorial.com/sap-hana-history-table/[/url]

Ďakujem, určite sa na to pozriem, ale dáta sa loadujú do tabuľky automaticky, okrem toho by som musel prerábať aj kód v Jave, ktorý spracováva *.xml výstupy, takže určite to nebude hneď.