Как уже говорили другие, REPLACE
это путь. Просто будьте осторожны, используя его, так как он на самом деле делает DELETE
и INSERT
на столе. Это нормально в большинстве случаев, но если у вас есть внешние ключи с ограничениями, такими как ON DELETE CASCADE
, это может вызвать некоторые большие проблемы.
Если у вас есть первичный ключ int (назовем его ID), вы можете использовать:
SELECT country FROM companies
WHERE id =
(
SELECT Min(id) FROM companies
GROUP BY Upper(country)
)
Нормализация регистра действительно кажется желательной - если встречаются все "Австралия", "Австралия" и "АВСТРАЛИЯ", какой из трех вариантов ответа вы бы выбрали в качестве "уникального с учетом регистра" ваш запрос, в конце концов? Если вы увлечены какой-то конкретной эвристикой (например, посчитайте, сколько раз они встречаются, и выберите наиболее популярные), это, безусловно, можно сделать, но это может потребовать огромного количества дополнительной работы - так сколько же для вас стоит такая привередливость ?
Метод, отличный от 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;
Теперь мы можем вывести
я. По одному из каждой категории? Т.е. три адреса?
ИЛИ
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;
Я думаю, что регулярные выражения могут помочь вам с шаблоном, который вы хотите использовать в строке поиска.
Для регулярного выражения вы можете определить UDF, который можно подготовить, просмотрев руководство. www.sqlteam.com/article/regular-expressions-in-t-sql
Спасибо.