Я только что закончил писать свою первую функцию PLSQL. Вот что он делает.Улучшение функции PL/pgSQL
Функция SQL пытается сбросить дублируемую временную метку до NULL.
- Из таблицы call_records найти всю временную метку, которые дублируются. (С использованием группы пути)
- цикла через каждый timestamp.Find все записи с такой же меткой времени (раз-1, так что только одна записью для данного времени является настоящее время)
- Из всех записей, найденных на шаге 2 обновление временной отметки в NULL
Вот как функция SQL выглядит.
CREATE OR REPLACE FUNCTION nullify() RETURNS INTEGER AS $$
DECLARE
T call_records.timestamp%TYPE;
-- Not sure why row_type does not work
-- R call_records%ROWTYPE;
S integer;
CRNS bigint[];
TMPS bigint[];
sql_stmt varchar = '';
BEGIN
FOR T,S IN (select timestamp,count(timestamp) as times from call_records where timestamp IS NOT NULL group by timestamp having count(timestamp) > 1)
LOOP
sql_stmt := format('SELECT ARRAY(select plain_crn from call_records where timestamp=%s limit %s)',T,S-1);
EXECUTE sql_stmt INTO TMPS;
CRNS := array_cat(CRNS,TMPS);
END LOOP;
sql_stmt = format('update call_records set timestamp=null where plain_crn in (%s)',array_to_string(CRNS,','));
RAISE NOTICE '%',sql_stmt;
EXECUTE sql_stmt ;
RETURN 1;
END
$$ LANGUAGE plpgsql;
Помогите мне лучше понять язык PL/pgSQL, предлагая мне, как это можно сделать лучше.
@a_horse_with_no_name: Здесь структура DB выглядит как \ d + call_records;
id integer primary key
plain_crn bigint
timestamp bigint
efd integer default 0
id | efd | plain_crn | timestamp
----------+------------+------------+-----------
1 | 2016062936 | 8777444059 | 14688250050095
2 | 2016062940 | 8777444080 | 14688250050095
3 | 2016063012 | 8880000000 | 14688250050020
4 | 2016043011 | 8000000000 | 14688240012012
5 | 2016013011 | 8000000001 | 14688250050020
6 | 2016022011 | 8440000001 |
Теперь
select timestamp,count(timestamp) as times from call_records where timestamp IS NOT NULL group by timestamp having count(timestamp) > 1
timestamp | count
-----------------+-----------
14688250050095 | 2
14688250050020 | 2
Все, что я хочу, чтобы обновить дубликат метки обнулить так, что только один из них запись имеет заданную отметку времени.
В коротком приведенном выше запросе должен возвращать результат, как это
select timestamp,count(timestamp) as times from call_records where timestamp IS NOT NULL group by timestamp;
timestamp | count
-----------------+-----------
14688250050095 | 1
14688250050020 | 1
Здесь нет необходимости в динамическом SQL. Я не думаю, что вам нужна функция вообще, это звучит так, как будто это можно сделать с помощью одного оператора обновления. Но без полного определения таблицы и некоторых выборочных данных это почти невозможно сказать –
@a_horse_with_no_name У меня есть вопрос. – Noobie