SQL ОШИБКА: Следующие столбцы не были найдены в участвующих таблицах - PullRequest
0 голосов
/ 22 марта 2020

Ниже приведен гипотетический запрос SQL в SAS. Эта таблица содержит столбец слов, начинающихся с A, B и C. Я создал макропеременную с этими значениями, разделенными запятыми, и я хочу создать отчет, в котором есть только слова, первая буква которых - B.

%let Letter=A, B, C;
proc sql;
select *
from Words
where Letter = %scan("&Letter", 2, ",");
quit;

По какой-то причине я получаю следующее: "ОШИБКА : Следующие столбцы не были найдены в участвующих таблицах: B "

Зачем оператору WHERE искать столбец с именем B вместо создания отчета обо всех строках, в которых есть первая буква слова Быть B?

Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 23 марта 2020

Макропроцессор SAS используется для генерации текста, который затем передается в SAS для выполнения, как если бы это был исходный текст программы. Вы использовали макро функцию% SCAN () для генерации текста B в позиции, где SAS ожидал имя переменной. В сообщении об ошибке говорится, что не удалось найти переменную B, потому что вы попросили ее использовать переменную B.

Перед использованием макрокода для генерации программы убедитесь, что вы знаете, какую программу вы хотите сгенерировать. Поэтому, возможно, вы захотите сгенерировать оператор:

select * from Words where Letter like "B%" ;

, который найдет все наблюдения в СЛОВАХ, если переменная LETTER начинается с прописной буквы B.

Чтобы сгенерировать это из вашей макропеременной ( сбивая нас с толку и называя LETTER), вы можете использовать код, подобный следующему:

select * from Words where Letter like "%scan(&letter,2,%str(,))%" ;

Обратите внимание, что ваше примерное значение LETTER на самом деле не сгенерирует то, что вы хотите. Вместо этого if сгенерирует этот код:

select * from Words where Letter like " B%" ;

, который ищет значения, начинающиеся с пробела, а затем заглавные буквы B. Это потому, что вы указали пробел после запятой.

Это очень проще использовать разделитель, отличный от запятой, при помещении списка значений в макропеременную. Например, вы можете использовать символ |.

%let list=A|B|C;
select * from Words where Letter like "%scan(&letter,2,|)%" ;
0 голосов
/ 23 марта 2020

Вероятно, более простые способы заставить это работать, но это два пути. Один изменяет ваш текущий подход, а другой иллюстрирует подход с шагом данных. Если вы используете% SCAN (), он возвращает B, который является переменной. Если вы используете SCAN (), он возвращает символ «B» вместо того, что вы хотите. Чтобы использовать опцию LIKE, я добавляю% в конец строки, чтобы указать, что начинается с B. В качестве альтернативы вы можете использовать SUBSTR (), чтобы получить первый символ и сравнить его отдельно.

SCAN также возвращает «B», поэтому я добавил полоску, чтобы удалить лишние пробелы. Я думаю, что в SCAN () есть опция для удаления пробелов, если вы хотите удалить функцию STRIP ().

data words;
input Letter $12.;
cards;
Apple
Bananas
Pears
Bread
Buffalo
Demo
Help
Suprprise
;;;;



%let Letter=A, B, C;
proc sql;
select *
from Words
where Letter like catt(strip(scan("&letter", 2, ",")), '%');
quit;

proc print data=words;
where letter =: strip(scan("&letter", 2, ","));
run;
0 голосов
/ 22 марта 2020

Я не уверен, как заставить это работать с макросами, но в SQL это будет выглядеть так:

select w.*
from Words w
where w.word LIKE 'A%' or 
      w.word LIKE 'B%' or 
      w.word LIKE 'C%' ;
...