Есть две таблицы (A и B), к которым я хочу присоединиться по дате.Это осложняется тем фактом, что даты не обязательно располагаются аккуратно между таблицами.То есть даты из таблицы B могут выходить за пределы или между записями в таблице A.
Я подозреваю, что должен быть простой способ сделать это в SQL / SAS, но я очень новичок воба и не видят как.Я был бы очень рад, если бы кто-то мог указать мне на конкретные решения, примеры или функции, которые я могу использовать для решения этой проблемы.Ниже я создал вымышленный случай для иллюстрации.
Это пример того, как может выглядеть таблица A (для одного участника):
Table A
-------------------------------------------+
participant start end
-------------------------------------------+
101 1-1-2010 26-4-2010
101 27-4-2010 2-10-2014
101 3-10-2014 4-1-2015
101 5-1-2015 31-8-2015
101 1-9-2015 12-10-2016
101 13-10-2016 31-12-2018
Ниже приведен пример таблицы B, для которой требуетсядля соединения с таблицей A. Как видите, даты для простого левого соединения слишком сильно отличаются:
Table B
---------------------------------------------------------+
participant start_date end_date Content
---------------------------------------------------------+
101 1-1-2012 31-8-2012 A
101 1-9-2012 31-8-2013 B
101 1-9-2013 31-8-2014 C
101 1-9-2014 2-10-2014 D
101 3-10-2014 31-8-2015 E
101 1-9-2015 31-1-2016 F
101 1-9-2015 31-1-2016 F
Идея для объединенной таблицы C состоит в том, что каждая строка таблицы A основана на данных изТаблица B. Я хочу выбрать запись из B, которая попадает в диапазон таблицы A. Если подходит несколько записей из B, следует использовать самую последнюю.Если в таблице B нет информации за этот период (как в случае с первой строкой), следует использовать ближайшую информацию.Иными словами, я хочу, чтобы в каждую строку А. добавлялась самая свежая информация о В.
Table C
----------------------------------------------------------------------+
participant startA endA startB endB Content
----------------------------------------------------------------------+
101 1-1-2010 26-4-2010 1-1-2012 31-8-2012 A
101 27-4-2010 2-10-2014 1-9-2013 31-8-2014 C
101 3-10-2014 4-1-2015 1-9-2014 2-10-2014 D
101 5-1-2015 31-8-2015 3-10-2014 31-8-2015 E
101 1-9-2015 12-10-2016 1-9-2015 31-1-2016 F
101 13-10-2016 31-12-2018 1-9-2015 31-1-2016 F
Это первый раз, когда я работаю с SAS и SQL, так что моя собственнаяусилия работают очень плохо.Ниже я объединяю эти две таблицы в процедуру, состоящую из нескольких шагов: сначала я создаю полное объединение, чтобы получить все возможные (соответствующие) перестановки таблиц A и B. Затем я вычисляю разницу в датах между данными из таблицы Aи B. Наконец, для каждого периода A я выбираю строку, в которой минимальная разница в датах между данными из исходных таблиц.
/* Create outer join of both tables*/
PROC SQL;
CREATE TABLE work.fulljoin AS
SELECT a.*, b.*
FROM work.table_A AS a
FULL JOIN work.table_B AS b ON a.participant = b.participant;
quit;
/* Group by ID and entry date of each period */
PROC SORT data=work.fulljoin;
BY participant startA;
RUN;
/* Calculate the date differences between tables A and B */
DATA work.fulljoin_wdelta;
SET work.fulljoin;
delta=abs(endA-endB);
RUN;
/* Remove unnecessary rows */
PROC SQL;
CREATE TABLE output.joined AS
SELECT * FROM work.fulljoin_wdelta
GROUP BY participant, startA
HAVING delta=min(delta);
QUIT;
Однако с большими наборами данных (миллионы строк в A и B) это становится запретительным.Кроме того, этот метод, строго говоря, не гарантирует, что вы будете получать самые последние данные B за каждый период A, то есть только те, которые ближе всего на дату окончания.