Можно ли сделать DISTINCT без учета регистра с помощью SAS (PROC SQL)?
Вопрос
Есть ли способ получить отдельные строки без учета регистра из этого SQL-запроса SAS?...
SELECT DISTINCT country FROM companies;
Идеальное решение состояло бы из одного запроса.
Результаты теперь выглядят следующим образом:
Australia
australia
AUSTRALIA
Hong Kong
HONG KONG
...где действительно требуется любая из 2-х отдельных строк
Можно было бы ввести данные в верхнем регистре, но это излишне изменяет значения способом, который не соответствует цели этого запроса.
Решение
Если у вас есть какой-то первичный ключ int (назовем его ID), вы могли бы использовать:
SELECT country FROM companies
WHERE id =
(
SELECT Min(id) FROM companies
GROUP BY Upper(country)
)
Другие советы
Нормализация регистра кажется целесообразной - если встречаются "Австралия", "australia" и "AUSTRALIA", то какой из трех вариантов вы бы хотели использовать в качестве "уникального" ответа на ваш запрос с учетом регистра?Если вы заинтересованы в какой-то конкретной эвристике (напримерпосчитайте, сколько раз они встречаются, и выберите самые популярные), это, конечно, можно сделать, но может потребовать огромного количества дополнительной работы - итак, сколько для вас стоит такая придирчивость?
Метод, отличный от SQL (на самом деле только один шаг, поскольку шаг данных просто создает представление), был бы:
data companies_v /view=companies_v;
set companies (keep=country);
_upcase_country = upcase(country);
run;
proc sort data=companies_v out=companies_distinct_countries (drop=_upcase_country) nodupkey noequals;
by _upcase_country;
run;
Может быть, я что-то упускаю, но почему бы просто не:
data testZ;
input Name $;
cards4;
Bob
Zach
Tim
Eric
Frank
ZacH
BoB
eric
;;;;
run;
proc sql;
create view distinctNames as
select distinct Upper(Name) from testz;
quit;
Это создает представление, в котором в качестве значений строк используются только различные имена.
Я думал в том же духе , что и Зак, но я подумал , что рассмотрю проблему на более сложном примере,
proc sql;
CREATE TABLE contacts (
line1 CHAR(30), line2 CHAR(30), pcode CHAR(4)
);
* Different versions of the same address - L23 Bass Plaza 2199;
INSERT INTO contacts values('LEVEL 23 bass', 'plaza' '2199');
INSERT INTO contacts values('level 23 bass ', ' PLAZA' '2199');
INSERT INTO contacts values('Level 23', 'bass plaza' '2199');
INSERT INTO contacts values('level 23', 'BASS plaza' '2199');
*full address in line 1;
INSERT INTO contacts values('Level 23 bass plaza', '' '2199');
INSERT INTO contacts values(' Level 23 BASS plaza ', '' '2199');
;quit;
Теперь мы можем выводить
i.По одному из каждой категории?Т. е. три адреса ?
или
ii.Или только один адрес ?если да , то какую версию нам следует предпочесть ?
Реализация варианта 1 может быть такой же простой, как :
proc sql;
SELECT DISTINCT UPCASE(trim(line1)), UPCASE(trim(line2)), pcode
FROM contacts
;quit;
Реализация варианта 2 может быть такой же простой, как:
proc sql;
SELECT DISTINCT UPCASE( trim(line1) || ' ' || trim(line2) ) , pcode
FROM contacts
;quit;
Из SAS 9:
процедура сортировки данных=input_ds sortseq=лингвистическая (сила= первичная);
by sort_vars;
бежать;
Я думаю, что регулярные выражения могут помочь вам с шаблоном, который вы хотите использовать в строке поиска.
Для регулярного выражения вы можете определить UDF, который можно подготовить, просмотрев руководство.www.sqlteam.com/article/regular-expressions-in-t-sql
Спасибо.