SQL-запрос — как преобразовать эту формулу Excel в запрос

#sql #excel #sqlite #sql-update

#sql #excel #sqlite #sql-обновление

Вопрос:

У меня есть существующая формула Excel. Логика такова:

  1. Начните поиск, когда даты в таблице 2 «Дата / время» больше, чем в таблице 1 «Open_Date»
  2. Прекратите поиск, когда даты в таблице 2 «Дата / время» меньше, чем таблица 1 «Close_Date»
  3. Если в таблице 1 «Действие» написано «Купить», то найдите, где в таблице 2 «Низкий» меньше, чем в таблице 1 столбец L «Фиксированный SLL».
  4. Если в таблице 1 «Действие» написано «Продать», то найдите, где в таблице 2 «High» меньше, чем в таблице 1 столбец L «FixedSL».
  5. Если найдено совпадение, верните «Дату / время» в таблице 2 и перепишите значение в таблице 1 «Time_Hit_Fixed_SL» для этой строки.

Вот примеры таблиц данных: Таблица 1

 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
 

Вывод forumula для первой строки таблицы 1 будет 01.06.2020 03:57 перезаписывать существующее значение в столбце «Time_Hit_Fixed_SL».

Чего я хочу добиться, так это выполнить это же действие в SQL с данными в 2 таблицах.

Я новичок в SQL и искал, но не смог найти правильное направление, чтобы получить указания, с чего начать с написания запросов для замены расширенной логики формулы Excel. Я ценю помощь и рекомендации!

Комментарии:

1. Отредактируйте свой вопрос и покажите нужные результаты. Также пометьте тегом базу данных, которую вы используете.

2. В SQLite единственным сопоставимым текстовым форматом даты и времени является YYYY-MM-DD hh:mm:ss . Измените формат ваших дат и добавьте также ожидаемый результат в вопрос, чтобы уточнить, чего вы хотите.

3. В таблице тип поля даты и времени — целое число. Это правильно? Пожалуйста, поясните, что еще мне нужно сказать об ожидаемом результате? Это строка после таблицы 2. Дайте мне знать, какая дополнительная информация требуется.

4. Если все даты и времени являются целыми числами, то все в порядке. Под ожидаемым результатом я подразумеваю таблицу 1 в том виде, в каком она будет после ее обновления.

Ответ №1:

Вы можете использовать функцию window 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
)
 

Смотрите демонстрацию.

Комментарии:

1. Когда я запускаю ОБНОВЛЕНИЕ, оно выдает одну ошибку: SQLiteStudio не удалось извлечь метаданные из запроса. Результаты не будут доступны для редактирования. И значения по-прежнему остаются неизменными. Есть какие-нибудь идеи, что я мог бы сделать, чтобы отладить это?

2. @JonathanStearns Как вы можете видеть в демонстрационной ссылке, оба запроса синтаксически корректны и возвращают ожидаемые результаты. Единственное, что я изменил в ваших примерах данных, это имя столбца Date/Time на Date_Time , потому что он содержит / . Поэтому в вашем коде вы должны использовать [Date/Time] вместо to Date_Time .

3. @JonathanStearns SQLiteStudio использует устаревшую версию SQLite: 3.24.0, которая даже не поддерживает оконные функции. Лучше использовать другой инструмент, такой как DB Browser для SQLite: sqlitebrowser.org

4. @JonathanStearns для SQLite 3.24.0 это будет работать: dbfiddle.uk /…

5. Вау, это сработало. Я знал, что это должен быть какой-то простой недосмотр. Я ценю терпение и помощь! Теперь это работает

Ответ №2:

Вы можете использовать инструкцию update следующим образом:

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

Комментарии:

1. Спасибо! Я попробую это сделать. Я ценю это.

2. Я получаю следующее: Ошибка при выполнении SQL-запроса к базе данных «Анализ торговли»: рядом с «.»: синтаксическая ошибка. Когда я гуглю это, он говорит, что код выполняется более чем по одному одновременно и разделяет его. Есть предложения?