Как узнать, есть ли какие-либо изменения в значениях между двумя верхними строками одной и той же таблицы

#sql #sql-server

#sql #sql-сервер

Вопрос:

ID MeterPointID Значение1 Значение2 CreatedUtc
1 4028 123 241 2021-01-29 09:58:24.977
2 4028 456 341 2021-01-29 09:56:39.517

В приведенной выше таблице обе строки идентифицируются одним и тем же идентификатором точки счетчика, что означает, что значения для второй строки были введены до ок. 4 минуты с первой строки, и за эти 4 минуты значения обеих строк меняются. Итак, здесь я просто хочу, чтобы параметр должен был установить true или false в зависимости от того, есть ли какие-либо изменения в значениях. Если да, то установите для параметра значение true, иначе false . Пожалуйста, помогите мне с подходящим ответом. Заранее спасибо.

Комментарии:

1. Какая у вас СУБД

2. sql server @D-Shih

3. Отредактируйте свой вопрос и покажите нужные результаты.

Ответ №1:

Если вам просто нужно значение true или false если максимальное и минимальное значения отличаются, вы можете использовать:

 select MeterPointID,
       (case when count(*) = 2 and
                  max(CreatedUtc) < dateadd(minute, 4, min(CreatedUtc)) and
                  (min(value1) <> max(value1) or min(value2) <> max(value2)
                  )
             then 'true' else 'false'
        end) as change_within_4_minutes
from t
group by MeterPointID;
 

Ответ №2:

Многие СУБД поддерживают как функции OLAP (те, у OVER(...) которых есть ), так и функцию NVL() (синонимы для этого: ISNUL() или IFNULL() ), которая возвращает первый параметр, если он не равен NULL , в противном случае второй. Если ваша СУБД выполняет оба, попробуйте следующее:

 WITH
-- your input, thanks for providing it in a COPY-PASTE-able format ...
indata(ID,MeterPointID,Value1,Value2,CreatedUtc) AS (
          SELECT 1,4028,123,241,TIMESTAMP '2021-01-29 09:58:24.977'
UNION ALL SELECT 2,4028,456,341,TIMESTAMP '2021-01-29 09:56:39.517'
)
SELECT
  *
, (
    NVL(value1<>LAG(value1) OVER (PARTITION BY meterpointid ORDER BY createdutc),FALSE)
 OR NVL(value1<>LAG(value2) OVER (PARTITION BY meterpointid ORDER BY createdutc),FALSE)
 ) AS has_changed
FROM indata;
 ID | MeterPointID | Value1 | Value2 |       CreatedUtc        | has_changed
---- -------------- -------- -------- ------------------------- -------------
  2 |         4028 |    456 |    341 | 2021-01-29 09:56:39.517 | f
  1 |         4028 |    123 |    241 | 2021-01-29 09:58:24.977 | t
 

Комментарии:

1. SQL Server ISNULL не использует NVL , в любом случае LAG имеет параметр «по умолчанию»

2. Параметр по умолчанию LAG(<expression>,<row_distance>,<default>) должен быть постоянным в большинстве СУБД; Сначала я попробовал этот бит, но две из моих СУБД пожаловались, поэтому я прибегнул к NVL() ISNULL() или IFNULL() , трем широко поддерживаемым функциям-синонимам.

3. Цитата: «по умолчанию может быть столбец, подзапрос или другое выражение, но оно не может быть аналитической функцией. значение по умолчанию должно быть совместимо с типом scalar_expression . Таким образом, вы можете использовать там все, что вам нравится. Вы должны проверить СУБД, которая помечена, прежде чем отвечать

4. Я исправлен. Хотя он не был помечен [SQL-Server], когда я формулировал свой ответ…