2012-01-18 3 views
0

Этот вопрос касается Postgres 8.3.Regex Replace in Postgresql 8.3

У меня есть строка, как

NULL + INTERVAL '3 days' > TIMESTAMPTZ '2012-01-01' - INTERVAL '1 month' 

обе стороны> оператора (который также может быть <, = или <>) содержат временную метку или NULL, а затем с + или - и интервал спецификации.

В случае, если временная метка NULL, я хочу избавиться от '+ INTERVAL' 3 дня ''. Это должно быть возможно с регулярными выражениями, но я совершенно не привык к их использованию. Как мне это сделать? Несколько примеров того, что я хочу:

1)

NULL + INTERVAL '3 days' > TIMESTAMPTZ '2012-01-01' - INTERVAL '1 month' 

должен быть изменен на

NULL > TIMESTAMPTZ '2012-01-01' - INTERVAL '1 month' 

2)

NULL + INTERVAL '3 days' > NULL - INTERVAL '1 month' 

должен быть изменен на

NULL > NULL 

3)

TIMESTAMPTZ '2012-01-01' + INTERVAL '3 days' > TIMESTAMPTZ '2012-02-01' - INTERVAL '1 month' 

следует оставить без изменений.

+1

Знаете ли вы, что '' 'NULL + anything''' оценивает' '' NULL''', поэтому вам не нужно менять строку, если вы хотите использовать ее в SQL? Пожалуйста, также отредактируйте свой вопрос, чтобы исправить кавычки, поскольку на данный момент они кажутся немного случайными :-). –

+0

Интересно, правда ли это из-за этой ошибки: 'ERROR: оператор не существует: интервал> метка времени без часового пояса LINE 1: SELECT NULL + INTERVAL '22 days '> TIMESTAMP' 2011-12-2 ...' , Я добавляю интервал в NULL, и он не может сравнивать интервал с меткой времени. Ну, я добавил «timestamp» позже, так что, возможно, поэтому ваш ответ был бы правильным, если бы у меня не было TIMESTAMP. Во всяком случае, «NULL + INTERVAL» 1 день »должен быть NULL по сравнению с меткой времени. – Leonard

+0

@ Leonard: Тим абсолютно прав, 'NULL' в сочетании с * ничего * повсеместно приводит к' NULL'. Не путайте ** тип данных ** с ** значением **. Вы можете сравнивать только значения, если определен оператор для задействованных типов данных. Это невозможно в PostgreSQL: 'SELECT NULL :: interval> NULL :: timestamp'. –

ответ

2

Regular Expression может выглядеть следующим образом:

SELECT regexp_replace(txt 
        , 'NULL [+-] INTERVAL ''.*?''' 
        , 'NULL' 
        , 'g') AS txt 
FROM (
    SELECT * FROM (VALUES 
    ('NULL + INTERVAL ''33 days'' > TIMESTAMPTZ ''2012-01-01'' - INTERVAL ''1 month''') 
    , ('NULL + INTERVAL ''3 days'' > NULL - INTERVAL ''1 month''') 
    , ('TIMESTAMPTZ ''2012-01-01'' + INTERVAL ''3 days'' > TIMESTAMPTZ ''2012-02-01'' - INTERVAL ''1 month''') 
    ) x(txt) 
) y 

Возвраты:

        txt 
---------------------------------------------------------------------------------- 
NULL > TIMESTAMPTZ '2012-01-01' - INTERVAL '1 month' 
NULL > NULL 
TIMESTAMPTZ '2012-01-01' + INTERVAL '3 days' > TIMESTAMPTZ '2012-02-01' - INTERVAL '1 month' 

quantifier*? является не жадный версия *.

+0

Спасибо. Я уже использовал '. *', Но он был слишком жадным. Почему мы должны использовать '?'? Он делает то, что мне нужно :). – Leonard

+0

@ Leonard: Круто. Я добавил информацию и ссылку на мой ответ. –

+0

Спасибо, я не знал об этом '*?' :). Готово! – Leonard