【问题标题】:SQL Query - how to translate this excel formula into a querySQL 查询 - 如何将此 excel 公式转换为查询
【发布时间】:2021-04-07 13:37:33
【问题描述】:

我有一个现有的 Excel 公式。逻辑是这样的:

  1. 当表 2“日期/时间”中的日期大于表 1“Open_Date”时开始查找
  2. 当表 2“日期/时间”上的日期小于表 1“Close_Date”时停止查找
  3. 如果表 1“操作”显示“买入”,则查找表 2“低”小于表 1 列 L“FixedSL”的位置。
  4. 如果表 1“Action”显示“卖出”,则查找表 2“高”小于表 1 列 L“FixedSL”的位置。
  5. 如果找到匹配项,则返回表 2 中的“日期/时间”并覆盖表 1“Time_Hit_Fixed_SL”中该行的值。

以下是数据表的示例: 表一

Open_Date,       Close_Date,   Action, FixedSL,  Time_Hit_Fixed_SL
6/1/2020 3:56,  6/1/2020 4:24,  Buy,   1.8502,   6/1/2020 5:01
6/1/2020 4:44,  6/1/2020 8:19,  Sell,  1.8411,   6/1/2020 10:12
6/1/2020 8:22,  6/1/2020 8:54,  Sell,  1.8335,   6/1/2020 10:12

表 2

Date/Time,        Open,     High,     Low,    Close
06/01/2020 03:57,  1.8503,  1.8503,  1.8501,  1.8501
06/01/2020 03:58,  1.8501,  1.8503,  1.8501,  1.8502
06/01/2020 03:59,  1.8501,  1.8504,  1.8501,  1.8504
06/01/2020 04:00,  1.8501,  1.8505,  1.8501,  1.8503
06/01/2020 04:01,  1.8504,  1.8504,  1.8504,  1.8504

表 1 第一行的论坛输出将是 06/01/2020 03:57 覆盖“Time_Hit_Fixed_SL”列中的现有值。

我想要完成的是在 SQL 中使用 2 个表中的数据执行相同的操作。

我是 SQL 新手并进行了搜索,但找不到正确的方向来获得有关从哪里开始编写查询以替换高级 excel 公式逻辑的指导。感谢您的帮助和指导!

【问题讨论】:

  • 编辑您的问题并显示您想要的结果。同时标记您正在使用的数据库。
  • 在 SQLite 中,唯一可比较的文本日期时间格式是 YYYY-MM-DD hh:mm:ss。更改日期的格式,并在问题中添加您的预期输出以阐明您想要的内容。
  • 表格中,日期时间字段类型为整数。那是对的吗?请说明我还需要对预期输出说些什么?它在表 2 之后的行。让我知道需要更多信息。
  • 如果所有的日期时间都是整数,那就没问题了。预期的输出是指 Table1 更新后的样子。

标签: sql excel sqlite sql-update


【解决方案1】:

可以如下使用更新语句:

update table1 t1
set t1.Time_Hit_Fixed_SL 
    = coalesce(select min(t2.date_time) 
                 from table2 t2
                where t2.date_time between t1.start_date and t2.end_Date
                  and (t1.action = 'Buy' and t2.high < t1.fixed_SL)
                       OR (t1.action = 'Sell' and t2.low < t1.fixed_SL))
                )
               ,t1.Time_Hit_Fixed_SL);

【讨论】:

  • 谢谢!我会尝试一下。我很感激。
  • 我明白了:在数据库“交易分析”上执行 SQL 查询时出错:“。”附近:语法错误。当我在谷歌上搜索它时,它说代码一次运行多个并且将其分隔开。有什么建议吗?
【解决方案2】:

您可以使用窗口函数MIN()获取Date/Time列的值。

如果您想要一个返回预期结果的SELECT 语句:

SELECT DISTINCT t1.Open_Date, t1.Close_Date, t1.Action,  
  COALESCE(
    MIN(
      CASE t1.Action
        WHEN 'Buy' THEN CASE WHEN t2.Low < t1.FixedSL THEN t2.Date_Time END
        WHEN 'Sell' THEN CASE WHEN t2.High < t1.FixedSL THEN t2.Date_Time END
      END
    )
    OVER (PARTITION BY t1.Open_Date, t1.Close_Date),
    t1.Time_Hit_Fixed_SL
  ) Time_Hit_Fixed_SL
FROM Table1 t1 LEFT JOIN Table2 t2
ON t2.Date_Time > t1.Open_Date AND t2.Date_Time < t1.Close_Date

如果要更新Table1

UPDATE Table1 AS t1
SET Time_Hit_Fixed_SL = COALESCE(
  (
    SELECT 
      MIN(
        CASE t1.Action
          WHEN 'Buy' THEN CASE WHEN t2.Low < t1.FixedSL THEN t2.Date_Time END
          WHEN 'Sell' THEN CASE WHEN t2.High < t1.FixedSL THEN t2.Date_Time END
        END
      )
    FROM Table2 t2  
    WHERE t2.Date_Time > t1.Open_Date AND t2.Date_Time < t1.Close_Date
  ),
  t1.Time_Hit_Fixed_SL
)

请参阅demo

【讨论】:

  • 当我运行 UPDATE 时,它给出了一个错误:SQLiteStudio 无法从查询中提取元数据。结果将不可编辑。并且值仍然没有改变。知道我可以做些什么来调试它吗?
  • @JonathanStearns 正如您在演示链接中看到的那样,两个查询在语法上都是正确的并返回您预期的结果。我在您的示例数据中唯一更改的是将列名称 Date/Time 更改为 Date_Time,因为它包含 /。所以在你的代码中你应该使用[Date/Time]而不是Date_Time
  • @JonathanStearns SQLiteStudio 使用过时的 SQLite 版本:3.24.0,它甚至不支持窗口函数。最好使用 DB Browser for SQLite 之类的其他工具:sqlitebrowser.org
  • @JonathanStearns 对于 SQLite 3.24.0 这将起作用:dbfiddle.uk/…
  • 哇,成功了。我知道这必须是一些简单的疏忽。我感谢耐心和帮助!现在可以使用了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
相关资源
最近更新 更多