开发者

MySQL Complex Inner Join

Suppose equity has a column called TickerID. I would like to replace the 111's with equity.TickerID. MySQL can't seem to resolve the scope and returns an unknown column when I try that. This SQL statement works but I need to run it for each ticker. Would be nice if I could get a full table.

SELECT Ticker,
    IF(tbl_m200.MA200_Count = 200,tbl_m200.MA200,-1) AS MA200,
    IF(tbl_m50.MA50_Count = 50,tbl_m50.MA50,-1) AS MA50,
    IF(tbl_m20.MA20_Count = 20,tbl_m20.MA20,-1) AS MA20
FROM equity
INNER JOIN 
(SELECT  TickerID,AVG(Y.Close) AS MA200,COUNT(Y.Close) AS MA200_Count FROM 
(
    SELECT Close,TickerID FROM equity_pricehistory_daily
    WHERE TickerID = 111
    ORDER BY Timestamp DESC LIMIT 0,200
) AS Y
) AS tbl_m200
USING(TickerID)

INNER JOIN 
(SELECT  TickerID,AVG(Y.Close) AS MA50,COUNT(Y.Close)  AS MA50_Count FROM 
(
    SELECT Close,TickerID FROM equity_pricehistory_daily
    WHERE TickerID = 111
    ORDER BY Timestamp DESC LIMI开发者_StackOverflow中文版T 50
) AS Y
) AS tbl_m50
USING(TickerID)

INNER JOIN 
(SELECT  TickerID,AVG(Y.Close) AS MA20,COUNT(Y.Close) AS MA20_Count FROM 
(
    SELECT Close,TickerID FROM equity_pricehistory_daily
    WHERE TickerID = 111
    ORDER BY Timestamp DESC LIMIT 0,20
) AS Y
) AS tbl_m20
USING(TickerID)


This seems to be some bug or "feature" of MySQL. Many persons seems to have the same problem with outer tables being out of scope.

Anyway... You could create functions that retrieve the information you want:

DROP FUNCTION IF EXISTS AveragePriceHistory_20;

CREATE FUNCTION AveragePriceHistory_20(MyTickerID INT)
RETURNS DECIMAL(9,2) DETERMINISTIC
RETURN (
    SELECT AVG(Y.Close)
    FROM (
        SELECT Z.Close
        FROM equity_pricehistory_daily Z
        WHERE Z.TickerID = MyTickerID
        ORDER BY Timestamp DESC
        LIMIT 20
    ) Y
    HAVING COUNT(*) = 20
);

SELECT
    E.TickerID,
    E.Ticker,
    AveragePriceHistory_20(E.TickerID) AS MA20
FROM equity E;

You would get NULL instead of -1. If this is undesirable, you could wrap the function-call with IFNULL(...,-1).


Another way of solving this, would be to select for the time-frame, instead of using LIMIT.

SELECT
    E.TickerID,
    E.Ticker,
    (
        SELECT AVG(Y.Close)
        FROM equity_pricehistory_daily Y
        WHERE Y.TickerID = E.TickerID
        AND Y.Timestamp > ADDDATE(CURRENT_TIMESTAMP, INTERVAL -20 DAY)
    ) AS MA20
FROM equity E;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜