首页 > 解决方案 > SQL - 通过循环执行设置值

问题描述

我想测试一些股票交易策略,并试图弄清楚我可以多么容易地使用 SQL (mySQL) 创建计算字段,而不是像以前那样使用 Python 使用 MongoDB。

我有大约 3,000 个代码的 5 年数据,我希望能够根据需要进行试验和设置其他列。对于 Python/MongoDB,这可能是一个非常缓慢的过程,虽然pandas在逐个代​​码的基础上计算和设置值方面非常直观,但我想如果我可以在 SQL 中完成相同的事情,我可以加快速度(并且我真的需要在 SQL 方面做得更好)。SQL 也比 MongoDB 体积小,而且我最终可能会得到大量计算字段。

具体来说,我必须执行以下操作:

  1. 根据表中不同的股票代码值创建一个数组。
  2. 循环遍历数组并按股票代码执行。
  3. 每个循环需要只选择与每个代码相关的行,然后执行需要引用多行的计算(例如,可以通过查找连续行上两个“关闭”字段之间的百分比变化来计算“更改”字段。

我发现了一些表明我可以在这里做 #3 的事情:SQL 行之间的差异

我想我只需要更改该查询以仅选择某个股票代码,但我真的不确定我是否可以执行 #1 和 #2。我看到我可以创建一个数组,但我不确定如何为数据库中的唯一值动态地执行此操作。对于#2,我看到可以创建while循环但不能创建for循环(尽管可能有多种方法可以将while循环用作for循环)。

我想如果我得到#1,我可以得到其余的,但任何建议都会受到赞赏。还有任何关于在 SQL 中执行此操作是否有意义的一般反馈。

标签: pythonmysqlsqlmongodb

解决方案


这只是一个基本示例,其中该字段Test是根据不同代码值内的代码索引设置的。诀窍是在字符串中使用逗号分隔的值来模拟数组,然后遍历字符串。

DROP PROCEDURE IF EXISTS set_fields;
DELIMITER //
CREATE PROCEDURE set_fields()
    BEGIN
        /* Get ticker count (for WHILE loop max iterations) and comma-separated tickers */
        SET @tickerCount = (
            SELECT COUNT(DISTINCT Ticker) FROM price_history
        );
        SET @tickers = (
            SELECT GROUP_CONCAT(Ticker) FROM (
                SELECT DISTINCT v.Ticker
                FROM price_history AS v
            ) as Tickers
        );
        SET @i = 0;
        
        WHILE @i < @tickerCount DO
            /* Loop through tickers in @tickers and call UPDATE */
        
            SET @comma = POSITION(',' IN @tickers);
            
            IF @comma = 0 THEN
                SET @ticker = @tickers;
            ELSE
                SET @ticker = SUBSTRING(@tickers, 1, @comma-1);
                SET @tickers = SUBSTRING(@tickers, @comma+1);
            END IF; 
            
            UPDATE price_history SET Test = @i WHERE Ticker = @ticker;
            SET @i = @i + 1;

        END WHILE;
        
    END //
DELIMITER ;

CALL set_fields();

推荐阅读