MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
Zdravim vospolok.
Pri robeni jednej webovej aplikacie som narazil na zdanlivo velmi jednoduchy problem, ktory som sice vyriesil (nemam to este natestovane, takze neviem, ci je to 100%ne funkcne riesenie), no neviem si s nim celkovo nejako elegantne/jednoznacne rady.
Majme
Tabulka A: id; datum; id2
1; 2009-12-17 10:12:00; 3
2; 2010-01-13 12:14:00; 14
3; 2009-01-13 14:02:44; 3
4; 2009-07-05 12:00:00; 20
5; 2009-07-05 12:00:00; 12
6; 2009-08-01 14:00:00; 20
Tabulka B: id, datum; id2; hodnota
1; 2008-10-01; 3; 3000
2; 2009-01-01; 3; 800
3; 2009-07-13; 3; 500
4; 2009-07-26; 3; 300
9; 2008-04-01; 12; 7500
10; 2008-10-21; 14; 5000
20; 2009-07-01; 20; 500
21; 2009-07-26; 20; 300
Potrebujem spravit JOIN Tab B na Tab A s tym, ze vysledok bude relevantna hodnota pre dany datum.
V JOINe teda operujem s A.id=B.id AND SUBSTRING(A.datum,1,10)>=B.datum
Tzn vysledok by mal vyzerat takto dajako:
A.id; A.datum; B.datum; A/B.id2; B.hodnota
1; 2009-12-17 10:12:00; 2009-07-26; 3; 300
2; 2010-01-13 12:14:00; 2008-10-21; 14; 5000
3; 2009-01-13 14:02:44; 2009-01-01; 3; 800
4; 2009-07-05 12:00:00; 2009-07-01; 20; 500
5; 2009-07-05 12:00:00; 2008-04-01; 12; 7500
6; 2009-08-01 14:00:00; 2009-07-26; 20; 300
Haluz je prave ta druha podmienka, s ktorou operujem => A.datum>=B.datum (resp. SUBSTRING(A.datum,1,10)>=B.datum, lebo A.datum je datetime, B.datum je date, ale to je irelevantne)
pretoze logicky ak mam v Tab B starsie hodnoty pre jedno ID2, tak pre nu vyhovuje viac riadkov. Ja potrebujem vzdy posledny zadany (tzn. s poslednym datumom).
Nejaky napad ako to elegantne vyriesit? LIMIT 1 pouzit neviem, ci mozem, sam som to vyriesil s vnorenymi join selectami, kde som to najprv ORDERol, potom GROUPol ale GROUP pouzivam tentokrat velmi nerad, lebo GROUPujem podla A.id a spolieham na to, ze zachova vzdy prvu B.hodnota :-(
Re: MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
Tak pokud to vazes takhle primitivne, tak je asi nejlepsi reseni vnoreny select primo do selekce
SELECT A.*, (SELECT * FROM B WHERE B.DATE > A.DATE LIMIT 1) FROM A;
Re: MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
Nejako nefunguje...
Tvoje riesenie vrati
A.id; A.datum; A/B.id2; B.hodnota; B.datum
1; 2009-12-17 10:12:00; 3; NULL; NULL
2; 2010-01-13 12:14:00; 14; NULL; NULL
3; 2009-01-13 14:02:44; 3; 500; 2009-07-13
4; 2009-07-05 12:00:00; 20; 500; 2009-07-13
5; 2009-07-05 12:00:00; 12; 500; 2009-07-13
6; 2009-08-01 14:00:00; 20; NULL; NULL
Stve ma na tom to, ze to vyzera trivialne, ale vsetky moje trivialne pokusy zlyhali :) :(
Re: MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
použít funkci max(date) v subselectu jsi zkusil?
Re: MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
Citace:
Původně odeslal
kocourleo
použít funkci max(date) v subselectu jsi zkusil?
Potrebujem najvyssi mensi alebo rovny oproti nejakemu. Nie cisto najvyssi.
Re: MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
Hele a co takhle tu druhou podmiku presunout do where ?
select * from A
join B on A.id = B.id
where SUBSTRING(A.datum,1,10)>=B.datum
Re: MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
V principu identicky problem jsme resili v praci, a dosli jsme k zaveru,ze to nema reseni v ramci jednoho sql dotazu. Resilo se to aplikacne. Bohuzel. Kdybyste nasli reseni, nasypu si popel na hlavu, a sproste ho ukradnu ;)
EDIT: nakonec si vzpominam, ze to nebylo reseny aplikacne, ale redundatnim bitem v DB, ktery u tech nejnovejsich radku rikal, ze je nejnovejsi. Updaty se delaly malo, tak to slo vykonove ukocirovat. Samozrejme je to prasecina..
Re: MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
KtK:
Tak ono to moze byt kludne barsaky konsky vnoreny SELECT, nebranim sa tomu. Proste to nechcem riesit na aplikacnej urovni, lebo ked tam budu desat-sta tisice poloziek, tak sa mozem posrat...
Ja som vyhutal iba toto:
SELECT X.id, X.datum, X.datum2, X.hodnota, X.id2
FROM A
LEFT JOIN (
SELECT A.id, A.datum, B.datum AS datum2, B.hodnota, B.id2
FROM A
LEFT JOIN B ON A.id2 = B.id2
AND CAST( A.datum AS DATE ) >= B.datum
ORDER BY B.datum DESC
) AS X ON X.datum = A.datum
GROUP BY X.id
ORDER BY NULL
Co sa sice tvari funkcne, ale prave kvoli tomu GROUP BY sa mi to velmi velmi velmi moc nepaci.
[edit]
Jezevec:
To Tvoje riesenie ma hacik v tom, ze v pripade, ze v B je viac moznosti vyhovujucich podmienke >=, tak to vrati kopec veci. Navyse nemas to nijako sortovane, takze ani nevies, ktora hodnota je pre Teba relevantna (teda... vies... najvyssia pre dane A.id, ale ono ti to nevyhodi v poradi a vyhodi ti ich vsetky)
Re: MySQL join 2 tabuliek s podmienkami = a >= za vysledku pre kazdy riadok z 1 TAB
How about this:
Kód:
SELECT a.*, b.*
FROM a
JOIN (
SELECT a.id, MAX(b.datum) AS datum
FROM a
LEFT JOIN b ON (b.id2 = a.id2 AND a.datum >= b.datum)
GROUP BY a.id
) temp ON (temp.id = a.id)
LEFT JOIN b ON (b.id2 = a.id2 AND b.datum = temp.datum);
Inak ako sam hovoris je to maly zazrak ze to Tvoje riesenie dava spravny vysledok pre tento specificky dataset. Ono uz len ten sort v tom vonkajsom left joine je v podstate zbytocny kedze poradie records nebude garantovane vo vysledku joinu... i ked v tomto pripade to "funguje".