[mysql] łączenie tabel

0

Witam. Problem następujący:

Tabela X posiada nagłówki:

ID | DATA | WALUTA | BID | ASK
..

Teraz wynik jaki chciałbym uzyskać (nowa tabela albo widok):

kolumna 1: data (w tabeli jest wiele takich samych dat jeśli to coś zmienia)
kolumna 2: średnia z BID dla zadanej daty ale tylko dla WALUTA="EUR/CHF"
kolumna 3: średnia z ASK dla zadanej daty ale tylko dla WALUTA="EUR/CHF"
kolumna 4: równanie BID/ASK

Czy ktoś ma pojęcie jak powinno wyglądać zapytanie?

Mam coś takiego (oczywiście to nie działa):

SELECT DATA,
AVG(ASK) FROM X WHERE WALUTA = "EUR/GBP",
AVG(BID) FROM X WHERE WALUTA = "EUR/CHF"
GROUP BY DATA

Ktoś pomoże?

0

kolumna 2: średnia z BID dla zadanej daty ale tylko dla WALUTA="EUR/CHF"
kolumna 3: średnia z ASK dla zadanej daty ale tylko dla WALUTA="EUR/CHF"
[...]
AVG(ASK) FROM X WHERE WALUTA = "EUR/GBP",
AVG(BID) FROM X WHERE WALUTA = "EUR/CHF"

Czemu GBP?

  1. Co znaczy

równanie BID/ASK

Tresc rownania? Wynik dla kazdego wiersza? Wynik sredni?

  1. Grupowanie po dacie czy po walucie w koncu?
0
johny_bravo napisał(a)

Czemu GBP?

  1. Co znaczy

równanie BID/ASK

Tresc rownania? Wynik dla kazdego wiersza? Wynik sredni?

  1. Grupowanie po dacie czy po walucie w koncu?

"EUR/GBP" to jest jedna z wartości w WALUTA
równanie czyli:
= BID/ASK

Chodzi o to aby uzyskać w każdym wierszu:

1 kolumna: DATA, czyli date
2 kolumnia: średnią wartość BID dla podanej daty i dla zadanej WALUTA
3 kolumna: średnia wartość ASK dla zadanej daty i WALUTA (tu waluta inna niż poprzednio)
4 wynik wyrażenia BID/ASK, czyli wynik drugiej kolumny podzielony przez trzecią

0

Czyli srednia wartosc bedzie sie powtarzac.
Cos takiego (mssql)?

select  
  data,
  (select avg(bid) from x where data = parent_x.data and waluta = parent_x.waluta) avg_bid,
  (select avg(ask) from x where data = parent_x.data and waluta = parent_x.waluta) avg_ask,
  case when ask = 0 then 0 else bid/ask end as bid_ask
from x as parent_x

Jak inny silnik to wystarczy zamienic case when ... end na odpowiednik, reszta powinna byc w porzadku.

0

MySQL ale nic zmieniać nie trzeba ino określić waluty:

SELECT 
  DATA,
  (SELECT avg(bid) FROM X WHERE DATA = parent_x.data AND waluta = "EUR/USD") avg_bid,
  (SELECT avg(ask) FROM X WHERE DATA = parent_x.data AND waluta = "EUR/GBP") avg_ask,
  case when ask = 0 then 0 else bid/ask end AS bid_ask
FROM X AS parent_x

Dzięki.

P.S.
Dostaelm jeszcze takie rozwiązanie:

SELECT DATA, X1.AVG_ASK, X2.AVG_BID
FROM X
LEFT JOIN (
SELECT DATA, AVG(ASK) AVG_ASK FROM X WHERE WALUTA="EURGBP" GROUP BY DATA
) X1 ON X1.DATA=X.DATA
LEFT JOIN (
SELECT DATA, AVG(BID) AVG_BID FROM X WHERE WALUTA="EURCHF" GROUP BY DATA
) X2 ON X2.DATA=X.DATA 
0

Chyba na jedno wychodzi. Optymalizator powinien podobnie wykonac oba zapytania :)

0
johny_bravo napisał(a)

Chyba na jedno wychodzi. Optymalizator powinien podobnie wykonac oba zapytania :)

I tak twoje rozwiązanie jest dla mnie lepsze.. Przynajmniej je rozumiem :)
Takie logiczne
[browar]

Co zrobić jak chce dodać no kolejny ASK z tym razem z WALUTA="EUR/USD";

jak zmienić tą linie bo dwa razy ask dać nie mogę, bo kombinuje i nic nie wychodzi..

case when ask = 0 then 0 else bid/ask end AS bid_ask

  1. Jakbym chciał z tego całą tabele zrobić automatycznie z kodu to jak to zrobić, bo wykonywanie przy 2 zmiennych tej kwerendy trwa ponad 1h (jak dodam 3 zmienna to juz jest 6h i dalej nie koniec) i to mi sie nie uśmiecha
0

czy ktoś może pomoc w pytaniu z powyższego popostu?

0

No dodaj analogicznie przeciez. A druga kwestia - co tam masz, ze trwa godzine?!

0

Załóż indeks na data. I w MySQL drugi sposób, który dostaleś (ten z left join) jest dużo lepszy. MySQL nie umie przekształcać podzapytań na joiny, które w 99 przyp. na 100 są dużo szybsze.

0

Fakt, ja ostatnio w temacie mssql, wiec ciagle mi sie wydaje, ze optymalizator prawie wszystko zalatwi ;) Z duzym naciskiem na 'prawie' :D

0

OK, Dzięki panowie..
Co do danych to mam tam ponad 600 tys linii danych a to jedynie wynik niecałego dnia (docelowo będzie ich z 100 mln do analizy) ..
Zapytanie robiło się ostatnio ponad 6h ..
Polecono mi abym zmienił stringi na liczbę czyli np zamiast "EUR/USD" stosował 1, takie coś ma przyśpieszyć kilkadziesiąt krotnie zapytanie.

pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1