MySQL Complex Inner Join

时间:2011-07-23 13:36:31

标签: mysql sql join

假设权益有一个名为TickerID的列。我想用equity.TickerID替换111。当我尝试时,MySQL似乎无法解析范围并返回未知列。这个SQL语句有效但我需要为每个自动收报机运行它。如果我能得到一张完整的桌子会很好。

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 LIMIT 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)

1 个答案:

答案 0 :(得分:0)

这似乎是MySQL的一些错误或“功能”。许多人似乎也有同样的问题,外围表超出了范围。

无论如何......您可以创建检索所需信息的函数:

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;

您将获得NULL而不是-1。如果这是不合需要的,您可以使用IFNULL(...,-1)包装函数调用。


解决此问题的另一种方法是选择时间范围,而不是使用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;