Найти максимальные и минимальные значения и соответствующее время вставки из таблицы - PullRequest
0 голосов
/ 01 мая 2020

У меня есть таблица, где несколько записей вставляются каждый день. Теперь я хочу выбрать максимальное и минимальное значение каждого дня данного месяца и их соответствующие вставленные значения DateTime в одном запросе.

Схема таблицы

DtTime   datetime
Value1   decimal(18,2)  

Пример данных

DtTime                    Value1    
--------------------------------    
2020-01-09 22:29:17.000    0.00
2020-01-09 22:30:41.000    0.40
2020-01-09 22:33:58.000    0.10
2020-01-09 22:34:59.000    2.49
2020-01-09 22:35:40.000    0.00
2020-01-10 00:33:07.000    0.10
2020-01-10 00:34:34.000    2.69
2020-01-10 00:37:06.000    2.67
2020-01-10 00:40:19.000    2.52
2020-01-15 08:34:34.000    0.69
2020-01-15 11:37:06.000    6.67
2020-01-15 04:40:19.000    2.52

Желаемый результат

Min     MinTime                   Max        MaxTime
-------------------------------------------------------------------    
0.00    2020-01-09 22:29:17.000   2.49      2020-01-09 22:34:59.000
0.10    2020-01-10 00:33:07.000   2.69      2020-01-10 00:34:34.000
0.69    2020-01-15 08:34:34.000   6.67      2020-01-15 11:37:06.000

аналогично для всех дней данного месяца, и если запись не существует в течение дня, то она будет показывать 0 во всех полях.

Ответы [ 3 ]

0 голосов
/ 01 мая 2020

Это даст вам необходимые данные;

(SELECT
MinV,
DtTime
FROM
    (SELECT
        CONVERT(VARCHAR(10),a1.DtTime,102) AS [Date],
        MIN(a1.Value1) AS 'MinV'
        FROM dbo.ValueEntries a1
        GROUP BY CONVERT(VARCHAR(10),a1.DtTime,102)
    ) b1
INNER JOIN
    (SELECT DISTINCT
        a2.DtTime, a2.Value1
    FROM dbo.ValueEntries a2) b2 ON b1.MinV = b2.Value1 AND b1.Date = CONVERT(VARCHAR(10),b2.DtTime,102)
) 

(SELECT
MaxV,
DtTime
FROM
    (SELECT
        CONVERT(VARCHAR(10),a1.DtTime,102) AS [Date],
        MAX(a1.Value1) AS 'MaxV'
        FROM dbo.ValueEntries a1
        GROUP BY CONVERT(VARCHAR(10),a1.DtTime,102)
    ) b1
INNER JOIN
    (SELECT DISTINCT
        a2.DtTime, a2.Value1
    FROM dbo.ValueEntries a2) b2 ON b1.MaxV = b2.Value1 AND b1.Date = CONVERT(VARCHAR(10),b2.DtTime,102)
) 

Выводит следующее;

MinV    DtTime
0.00    2020-01-09 22:29:17.000
0.00    2020-01-09 22:35:40.000
0.10    2020-01-10 00:33:07.000
0.69    2020-01-15 08:34:34.000

MaxV    DtTime
2.49    2020-01-09 22:34:59.000
2.69    2020-01-10 00:34:34.000
6.67    2020-01-15 11:37:06.000

Теперь, в зависимости от того, что вы действительно хотите делать с данными, вы можете экспортировать это или добавьте его в панель отчетности.

Однако, если вы рассматривали возможность динамического использования этого на панели инструментов или в каком-либо приложении, я бы порекомендовал вам построить данные в кубы, как указано выше, а не пытаться выводить их все сразу.

Если вы ищете регулярный отчет о дате по группам, рассмотрите дополнительный столбец, чтобы сделать вашу жизнь намного более понятной.

DtTime   datetime
DtSpec   date
Value1   decimal(18,2)

Это также, несомненно, значительно облегчит выполнение ваш сервер.

Кроме того, не забывайте использовать первичные ключи в ваших таблицах, так как это упрощает явные объединения для манипулирования вашими данными, поэтому ваша новая схема должна выглядеть примерно так;

ID       INT(PK)
DtTime   datetime
DtSpec   date
Value1   decimal(18,2)

Надеюсь, это поможет вам лучше понять, как двигаться вперед. Удачи!

0 голосов
/ 01 мая 2020

SQL На сервере нет функций «первого» и «последнего» агрегирования. Но вы можете использовать оконные функции для этой цели:

select distinct cast(dttime as date) as dte,
       min(Value1) over (partition by cast( dttime as Date) ) as maxValue,
       first_value(dttime) over (partition by cast( dttime as Date) order by value1 asc) as min_time,
       max(Value1) over (partition by cast( dttime as Date) ) as maxValue,
       first_value(dttime) over (partition by cast( dttime as Date) order by value1 desc) as max_time
from t
order by dte;

Здесь - это db <> скрипка.

0 голосов
/ 01 мая 2020

Используйте group by или Over with partition by. См. dbfiddle

 Select min(Value1) as minId
          , min(DtTime) as MinDtTime
          , max(Value1) as maxId
          , max(DtTime) as MaxDtTime
    from YourTable
    group by Cast( DtTime as Date)

ИЛИ

Select distinct
     min(Value1) OVER (PARTITION BY Cast( DtTime as Date) ) as minId
    , min(DtTime) OVER (PARTITION BY Cast( DtTime as Date)) as MinDtTime
    , max(Value1) OVER (PARTITION BY Cast( DtTime as Date)) as maxId
    , max(DtTime) OVER (PARTITION BY Cast( DtTime as Date)) as MaxDtTime
from YourTable
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...