E 'possibile fare un case-insensitive DISTINCT con SAS (PROC SQL)?
Domanda
C'è un modo per ottenere le case-insensitive righe distinte da questa query SQL SAS? ...
SELECT DISTINCT country FROM companies;
La soluzione ideale consisterebbe in una singola query.
Risultati apparire come:
Australia
australia
AUSTRALIA
Hong Kong
HONG KONG
... dove qualsiasi 2 righe distinte è veramente necessario
Si potrebbe maiuscolo i dati, ma questo cambia inutilmente valori in modo che non soddisfa lo scopo di questa domanda.
Soluzione
Se avete qualche chiave int primaria (chiamiamolo ID), è possibile utilizzare:
SELECT country FROM companies
WHERE id =
(
SELECT Min(id) FROM companies
GROUP BY Upper(country)
)
Altri suggerimenti
caso normalizzazione fa sembrare consigliabile - se 'l'Australia', 'Australia' e 'AUSTRALIA' tutti si verificano, che uno dei tre vorresti come la risposta "unico sensibile-caso" per la tua ricerca, dopo tutto? Se siete appassionati di alcune euristiche specifici (ad esempio contare quante volte si verificano e scegliere il più popolare), questo può sicuramente essere fatto, ma potrebbe essere una quantità enorme di lavoro extra - sì, quanto è tale persnicketiness vale a voi ?
Un metodo non-SQL (in realtà solo un singolo passo come il passo di dati crea solo una vista) potrebbe essere:
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;
Forse mi manca qualcosa, ma perché non solo:
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;
Ciò crea una vista con solo nomi diversi come valori di riga.
Stavo pensando lungo le stesse linee come Zach , ma ho pensato guardare il problema con un esempio più elaborato,
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;
Ora siamo in grado di produrre
io. Uno per ogni categoria? Vale a dire tre indirizzi?
o
ii. O solo un indirizzo? in caso affermativo quale versione dovremmo preferire?
L'implementazione caso 1 può essere semplice come:
proc sql;
SELECT DISTINCT UPCASE(trim(line1)), UPCASE(trim(line2)), pcode
FROM contacts
;quit;
L'implementazione caso 2 può essere semplice come:
proc sql;
SELECT DISTINCT UPCASE( trim(line1) || ' ' || trim(line2) ) , pcode
FROM contacts
;quit;
Da SAS 9:
proc sort data = input_ds sortseq = linguistica (strengh = primario);
by sort_vars;
run;
Credo espressioni regolari possono aiutare con il modello che si desidera avere nella stringa di ricerca.
Per l'espressione regolare si può definire un'UDF che può essere preparato a vedere il tutorial. www.sqlteam.com/article/regular-expressions-in-t-sql
Grazie.