В kdb есть ли эквивалент левого соединения для нескольких столбцов с неравенствами (например, модифицируемая версия соединений asof)? - PullRequest
1 голос
/ 19 марта 2020

У меня есть таблица заказов в kdb, в которой есть идентификаторы заказов, время ввода заказов и время удаления заказов, как показано ниже:

+----+-------------------------+-------------------------+
| id |        entrytime        |       deletetime        |
+----+-------------------------+-------------------------+
|  1 | 2020.01.01T00:00:00.000 | 2020.01.01T04:00:00.000 |
|  2 | 2020.01.01T00:00:00.000 | 2020.01.01T03:59:58.000 |
|  3 | 2020.01.01T00:00:00.000 | 2020.01.01T00:00:02.000 |
|... | ...                     | ...                     |
+----+-------------------------+-------------------------+

Я хотел бы преобразовать это в представление, которое показывает открытые / активные заказы каждую секунду, как показано ниже:

+-------------------------+---------+
|        datetime         | openids |
+-------------------------+---------+
| 2020.01.01T00:00:00.000 | 1 2 3   |
| 2020.01.01T00:00:01.000 | 1 2 3   |
| 2020.01.01T00:00:02.000 | 1 2     |
| 2020.01.01T00:00:03.000 | 1 2     |
| ...                     | ...     |
| 2020.01.01T03:59:57.000 | 1 2     |
| 2020.01.01T03:59:58.000 | 1       |
| 2020.01.01T03:59:59.000 | 1       |
| 2020.01.01T04:00:00.000 |         |
+-------------------------+---------+

Что мне нужно, это эквивалент SELECT * FROM table1 LEFT JOIN ON datetime >= entrytime and datetime < deletetime в кДБ.

Я пробовал объединение окон, но без особого успеха.

Буду очень признателен за любую помощь в этом.

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Есть много вариантов сделать это. Пожалуйста, посмотрите один из них ниже. Но для начала я бы преобразовал время в timestamp тип, с datetime трудно справиться и он считается устаревшим.

t: ([] id: 1 2 3
    ; entrytime: 3#2020.01.01D
    ; deletetime: 2020.01.01D04:00:00 2020.01.01D03:59:58 2020.01.01D00:00:02);
t: update datetime: {x+00:00:01*til `int$1e-9*y-x}'[entrytime;deletetime] from t;
t: ungroup t;
t: select openid: id by datetime from t;
timetable: ([]datetime: {x+00:00:01*til 2+`int$1e-9*y-x} . value exec min datetime
    , max datetime from t);
t: timetable lj t;
t

Объяснение:

  1. Добавить столбец даты и времени в таблица t, которая отслеживает все времена, когда заказ доступен с шагом в одну секунду
  2. ungroup таблица t для получения идентификатора <-> отображение доступного времени
  3. таблица групп t по доступному времени. Это уже дает результат, который вы ищете. Но могут быть промежутки для времен, когда нет доступных заказов
  4. Заполните пробелы, присоединившись к timetable, который все время находится в диапазоне времени создания / удаления ордеров, с таблицей t.
0 голосов
/ 19 марта 2020

Это можно сделать без использования какого-либо соединения и в одной строке:

q)`datetime xgroup ungroup select id,datetime:entrytime+"v"$til each"j"$deletetime.second-entrytime.second from t
datetime               | id
-----------------------| -----
2020.01.01T00:00:00.000| 1 2 3
2020.01.01T00:00:01.000| 1 2 3
2020.01.01T00:00:02.000| 1 2
2020.01.01T00:00:03.000| 1 2
2020.01.01T00:00:04.000| 1 2
...

Это позволит получить разницу во времени между временем входа и удаления, используя только компонент секунд, используя .second. Затем приведение к длинному с использованием "j"$ даст число, на котором можно использовать til each. Наконец, приведение ко второму типу с использованием "v"$ и добавление исходного времени записи в эти списки создаст список секунд, для которых активен каждый идентификатор:

q)select id,datetime:entrytime+"v"$til each"j"$deletetime.second-entrytime.second from t
id datetime                                                                  ..
-----------------------------------------------------------------------------..
1  2020.01.01T00:00:00.000 2020.01.01T00:00:01.000 2020.01.01T00:00:02.000 20..
2  2020.01.01T00:00:00.000 2020.01.01T00:00:01.000 2020.01.01T00:00:02.000 20..
3  2020.01.01T00:00:00.000 2020.01.01T00:00:01.000                           ..

Наконец, использование ungroup приведет к разгруппировке В столбце datetime, а затем немедленно с помощью xgroup в столбце datetime сгруппировать идентификаторы, которые активны в течение этой секунды.

...