Intereting Posts
Преобразование массива целых чисел для использования в предложении SQL «IN» Сохранение позиций позиций (для заказа) в базе данных эффективно Самый быстрый случайный выбор WHERE column X – Y (NULL) SQL – Получить дату большинства поданных голосов Какова наилучшая практика для преобразования данных между приложениями Как изменить порт по умолчанию mysql от 3306 до 3360 Как использовать другие поля таблицы в качестве критерия для MS Access Как присоединиться к COUNT из таблицы, а затем применить этот COUNT к другому JOIN Какой SQL-запрос или представление покажут «динамические столбцы», Невозможно добавить ограничение внешнего ключа в поле даты Создание отчета с доступом и списком SharePoint ORACLE Литье DATE в TIMESTAMP с временной зоной с OFFSET Как получить рекурсивный уровень с помощью иерархии SQL Server 2012? выберите 10 строк в день с заказом Использование fn_Split в SQL-запросе

Как сохранить последнюю контрольную точку в sql, которая будет использоваться для следующей строки

Есть ли способ сохранить последний результат итерации строки и использовать ее для следующей итерации строки?

Например, у меня есть таблица say ( Time_Table ).

 __ Key type timeStamp 1 ) 1 B 2015-06-28 09:00:00 2 ) 1 B 2015-06-28 10:00:00 3 ) 1 C 2015-06-28 11:00:00 4 ) 1 A 2015-06-28 12:00:00 5 ) 1 B 2015-06-28 13:00:00 

Теперь предположим, что у меня есть exceptionTime из 90 минут, который является постоянным. Если я начну проверять свой Time_Table тогда:

  1. для первой строки, так как нет строки до 09:00:00, она будет напрямую помещать эту запись в мою целевую таблицу. Теперь моя точка отсчета находится в 9:00:00.

  2. Для второй строки в 10:00:00, последняя контрольная точка была 09:00:00 а TIMESTAMPDIFF(s,09:00:00,10:00:00) – 60, что меньше требуемого 90. Я делаю не добавляйте эту строку в мою целевую таблицу.

  3. Для третьей строки последнее зарегистрированное исключение было в 09:00:00 а TIMESTAMPDIFF(s,09:00:00,11:00:00) – 120, что больше требуемых 90, поэтому я выбираю эту запись и устанавливаю ориентир до 11:00:00 .

  4. Для четвертой строки TIMESTAMPDIFF(s,11:00:00,12:00:00) . Точно так же он не будет сохранен.

  5. Этот снова сохраняется.

Целевая таблица

 __ Key type timeStamp 1 ) 1 B 2015-06-28 09:00:00 2 ) 1 C 2015-06-28 11:00:00 3 ) 1 B 2015-06-28 13:00:00 

Есть ли способ решить эту проблему purely in SQL ?

Мой подход:

 SELECT * FROM Time_Table A WHERE NOT EXISTS( SELECT 1 FROM Time_Table B WHERE A.timeStamp > B.timeStamp AND abs(TIMESTAMPDIFF(s,B.timeStamp,A.timeStamp)) > 90 ) 

Но это на самом деле не работает.

Это невозможно, используя только чистый SQL в Vertica. Чтобы сделать это в чистом SQL, вы должны иметь возможность выполнять рекурсивный запрос, который не поддерживается в продукте Vertica. В других продуктах базы данных вы можете сделать это, используя предложение WITH. Для Vertica вам придется делать это в логике приложения. Это основано на утверждении: «Каждое предложение WITH в блоке запроса должно иметь уникальное имя. Попытка использовать псевдонимы одинакового имени для запросов запроса предложения WITH в одном блоке запроса вызывает ошибку. WITH clauses не поддерживает INSERT, DELETE, и UPDATE, и вы не можете использовать их рекурсивно "из документации Vertica 7.1.x

Определенно ДА, (Не в чистом SQL) либо используют LAG ( начиная с версии 7.1.x ), зависит от какой версии Vertica вы используете или создаете пользовательский UDx (пользовательские расширения)

UDx в Java для доступа к предыдущей строке, которая действует как LAG только с одним шагом (производительность hastag #) ( github, полный примеров udx )

 public class UdxTestFactory extends AnalyticFunctionFactory { @Override public AnalyticFunction createAnalyticFunction(ServerInterface srvInterface) { return new Test(); } @Override public void getPrototype(ServerInterface srvInterface, ColumnTypes argTypes, ColumnTypes returnType) { argTypes.addInt(); argTypes.addInt(); returnType.addInt(); } @Override public void getReturnType(ServerInterface srvInterface, SizedColumnTypes argTypes, SizedColumnTypes returnType) throws UdfException { returnType.addInt(); } private class Test extends AnalyticFunction { @Override public void processPartition(ServerInterface srvInterface, AnalyticPartitionReader inputReader, AnalyticPartitionWriter outputWriter) throws UdfException, DestroyInvocation { SizedColumnTypes inTypes = inputReader.getTypeMetaData(); ArrayList<Integer> argCols = new ArrayList<Integer>(); inTypes.getArgumentColumns(argCols); outputWriter.setLongNull(0); while (outputWriter.next()) { long v1 = inputReader.getLong(argCols.get(0)); // previous row inputReader.next(); long v2 = inputReader.getLong(argCols.get(0)); // curent row outputWriter.setLong(0, v2 - v1); } } } } 

компилировать и комбинировать скомпилированные классы в одну банку, назвал ее TestLib.jar для простоты

 $ javac -classpath /opt/vertica/bin/VerticaSDK.jar /opt/vertica/sdk/BuildInfo.java UdxTestFactory.java -d . $ jar -cvf TestLib.jar com/vertica/sdk/BuildInfo.class com/vertica/JavaLibs/*.class 

Загрузить библиотеку и функцию

 CREATE OR REPLACE LIBRARY TestFunctions AS '/home/dbadmin/TestLib.jar' LANGUAGE 'JAVA'; CREATE OR REPLACE ANALYTIC FUNCTION lag1 AS LANGUAGE 'java' NAME 'com.vertica.JavaLibs.UdxTestFactory' LIBRARY TestFunctions; 

И .. используйте его

 SELECT lag1(col1, null) OVER (ORDER BY col2) AS col1_minus_col2 FROM ...