2013-06-05 9 views
7
  • Używam amazon przesunięcie ku czerwieni, jak mój hurtowni danych
  • Mam pole (pole1) typu string. Niektóre ciągi zacząć z czterech cyfr i innymi literami:

„alpha test”
„test 1382 beta”SQL Server IsNumeric() równowartość w Amazon redshifcie

  • chcę odfiltrować wiersze gdzie łańcuch nie rozpocznie z czterech numery
  • Patrząc na dokumentację redshift, nie uważam, że jest liczbą lub isnumeric to funkcje. Wydaje się, że najlepszą funkcją jest funkcja "podobna".
  • że próbował

    którym lewy (pole1, 4), takie jak '[0-9], [0-9], [0-9], [0-9]:

to nie pracy i z linku poniżej wydaje się przesunięcie ku czerwieni nie może wspierać że:

https://forums.aws.amazon.com/message.jspa?messageID=439850

tam jest błąd w klauzuli „gdzie”? jeśli nie, a klauzula nie jest obsługiwana w redshift, czy istnieje sposób filtrowania? Myślałem o użyciu obsady

cast(left(field1,4) as integer) 

a następnie przechodząc nad wiersz, jeśli generowany błąd, ale nie wiem, jak to zrobić w Amazon przesunięciu ku czerwieni. lub jest jakiś inny proxy dla filtra isnumeric.

dzięki

+0

Twój przykład nie działa w PostgreSQL. ILIKE nie obsługuje wyrażeń regularnych. Amazon Redshift bazuje na PostgreSQL 8.0.2, więc może możesz użyć operatora SIMILAR http://www.postgresql.org/docs/8.0/interactive/functions-matching.html#FUNCTIONS-SIMILARTO- REGEXP, ponieważ SIMILAR to może być słowo kluczowe. .. niektóre jak podciąg SELECT ("1234 xxx" Z 1 NA 4) podobne do "[\ d] {4}"; –

Odpowiedz

3

Wydaje się, że przesunięcie ku czerwieni nie obsługuje jedną z następujących czynności:

where left(field1,4) like '[0-9][0-9][0-9][0-9]' 
where left(field1,4) ~ '^[0-9]{4}' 
where left(field1,4) like '^[0-9]{4}' 

co wydaje się do pracy jest:

where left(field1,4) between 0 and 9999 

ta zwraca wszystkie wiersze, które zaczynają z czterech znaków numerycznych.

wydaje się, że nawet jeśli pole 1 jest ciągiem znaków, funkcja "między" interpretuje lewy (field1,4) jako pojedynczą liczbę całkowitą, gdy znaki łańcuchowe są numeryczne (i nie daje błędu, gdy nie są liczbowe). Sprawdzę, czy znajdę problem. Na przykład nie zajmuję się mniej niż 1000, więc zakładam, ale nie jestem pewien, że 0001 jest interpretowane jako 1.

+1

Nie sądzę, że to jest poprawne. Podaj następujący przykład: 'select count (*) from a thing = '3081_xl7' i rzecz między 0 a 999999;' To spowoduje powrót 1. W tym przypadku 'rzeczą' jest kolumna' varchar'. – bstempi

4

spróbować czegoś jak:

where field1 ~ '^[0-9]{4}' 

Będzie dopasować dowolny ciąg znaków, który rozpoczyna się z 4 cyfr.

+0

dzięki Igor i Pavel. niestety nie wygląda na to, że powyższe działa z redshift. następujące zdanie: – Elm

+0

Przepraszam, komentarz został odcięty ... dzięki Igorowi i Pavelowi. niestety nie wygląda na to, że powyższe działa z redshift. Kiedy dodaję klauzulę "where field1 ~ '^ [0-9] {4}" do instrukcji, instrukcja zwraca: "ERROR: Dopasowanie wyrażenia regularnego nie jest obsługiwane [SQL State = XX000]". Jeśli spróbuję "gdzie pole1 odpowiada"^[0-9] {4} ", zwraca pustą tabelę, ale bez błędu. Jeśli spróbuję "gdzie pole1 przypomina" $ ", zwraca wszystkie wiersze. Wygląda na to, że przesunięcie w kierunku czerwieni obsługuje tylko "polubienie", ale nie resztę wyrażenia. Jakieś pomysły? Dzięki jeszcze raz. – Elm

+0

Jeśli chcesz przyjrzeć się bliżej, jest to link do dokumentów redshift dotyczących "like": Elm

2

wygląda to, czego szukasz jest funkcja similar to (Redshift doc)

where left(field,4) similar to [0-9]{4} 
+0

Ten działał dobrze dla mnie, z wyjątkiem tego, że musisz używać apostrofów: gdzie w lewo (pole 4) podobne do "[0-9] {4}" – najczuk

2
where regexp_instr(field1,'^[0-9]{4}') = 0 

usunie wiersze zaczynające się od 4 cyfr (powyżej regexp_instr powróci 1 dla wierszy z pole1 zaczynając 4 cyfry)

6

Mimo że minęło wiele czasu od zadawania tego pytania, nie znalazłem odpowiedniej odpowiedzi. Dlatego czuję się zobowiązany do dzielenia się swoim rozwiązaniem, które działa dobrze na moim klastrze Redshift już dziś (marzec 2016 r.).

Funkcja UDF jest:

create or replace function isnumeric (aval VARCHAR(20000)) 
    returns bool 
IMMUTABLE 
as $$ 
    try: 
     x = int(aval); 
    except: 
     return (1==2); 
    else: 
     return (1==1); 
$$ language plpythonu; 

Wykorzystanie byłoby:

select isnumeric(mycolumn), * from mytable 
    where isnumeric(mycolumn)=false 
+0

działa świetnie! Dzięki :) –

1

Próbowaliśmy następujące pracował dla większości naszych scenariuszy:

columnn ~ „^ [- ] {0,1} [0-9] {1,} [.] {0,1} [0-9] {0,} $ '

To będzie dodatnie, ujemne, całkowite i zmiennoprzecinkowe nu mbers.