Проблема перекрестного соединения в операторе SQL (SAS)

Может ли кто-нибудь объяснить мне, почему это настаивает на создании декартова продукта при объединении? Мне казалось бы логичным использовать index. Есть ли способ заставить его использовать индекс (вы можете видеть, что я пробовал, но он игнорирует мой оператор idxname).

Приведенный ниже пример - это самый простой способ воспроизвести возникшую у меня проблему, и это не мой реальный код.

Создайте несколько тестовых данных:

data all_periods;
  do date=mdy(1,1,2015) to mdy(4,1,2015);
    do hour=0 to 23;
      do minute=0 to 59; 
        period_start = dhms(date,hour,minute,0);
        output;
      end;
    end;
  end;
run;

Создайте индекс на тестовых данных:

proc sql noprint;
  create index period_start on all_periods;
quit;

Выполните самостоятельное присоединение:

proc sql noprint _method;
  create table concurrent as 
  select a.period_start,
         count(*) as result
  from all_periods a
  join all_periods (idxname=period_start) b on b.period_start lt a.period_start
  group by 1
  ;
quit;

person Robert Penridge    schedule 20.04.2015    source источник


Ответы (1)


Неэквивалентные соединения часто не используют индексы. Я бы действительно рекомендовал вам сделать это на этапе обработки данных, используя retain. Однако вы можете попробовать эту версию в proc sql:

select a.period_start,
       (select count(*)
        from all_periods b
        where b.period_start < a.period_start
       ) as result
from all_periods a;

Большинство баз данных имеют встроенные накопительные суммы с использованием оконных функций. Однако SAS не поддерживает их изначально. Итак, proc sql - не лучший способ сделать этот расчет.

person Gordon Linoff    schedule 20.04.2015
comment
Ага, это. Очевидно, что если ваш реальный код делает что-то совершенно другое, вам нужно либо переосмыслить это, либо опубликовать что-то более близкое к вашему реальному коду; но в целом шаг с данными SAS хорош именно поэтому: он изначально способен делать то, с чем SQL труднее работать (во всяком случае, ANSI). - person Joe; 21.04.2015
comment
Спасибо, он определенно ответил на мой главный вопрос: должен ли я делать это в SQL или нет. Я, вероятно, вскоре опубликую следующий вопрос с точным примером того, что я пытался сделать (потому что SQL был бы намного проще, чем этап данных), но сначала мне нужно получить некоторые результаты. - person Robert Penridge; 21.04.2015
comment
@joe. . . Это определенно не тот пример, когда ANSI SQL не оправдывает ожиданий. ANSI SQL поддерживает совокупные суммы, но не все реализации баз данных (например, proc sql) поддерживают эту часть стандарта. Я не собираюсь начинать дискуссию о достоинствах одного по сравнению с другим, но SQL тоже прекрасен. Одна из причин заключается в том, что он изначально параллелен и может использовать преимущества гораздо большего количества оборудования, которое базируется на SAS. - person Gordon Linoff; 21.04.2015
comment
@GordonLinoff Достаточно честно. Они оба по-своему великолепны. :) Я не собирался особо сравнивать SAS с SQL - но «базовый SAS» с «proc SQL» - как и внутри SAS, определенно есть места, где один превосходит другой. - person Joe; 21.04.2015