SQL-запрос для суммирования значений из строк в течение определенного периода времени (в пределах идентификатора)? - PullRequest
0 голосов
/ 10 апреля 2019

Мне нужно суммировать значения (Amount2) из ​​строк за определенный период времени (с датой 18 часов или 22 часа), а также нужно знать, сколько строк было использовано.Это суммирование значений должно быть сделано в пределах идентификационного номера.Кто-нибудь может помочь с этим?

Первые строки таблицы T1:

ID  PickupDateTime          Amount2 DifferenceToPrevious
1   2019-04-02 04:44:19.000 6458    0d 00:13:17:000
1   2019-04-02 04:31:02.000 5385    0d 02:34:50:000
1   2019-04-02 01:56:12.000 1545    0d 18:06:18:000
1   2019-04-01 07:49:54.000 3466    1d 02:23:51:000
1   2019-03-31 05:26:03.000 7505    0d 00:13:53:000
1   2019-03-31 05:12:10.000 5080    0d 03:28:18:000
1   2019-03-31 01:43:52.000 1166    0d 18:02:49:000
1   2019-03-30 07:41:03.000 2991    1d 02:39:49:000
1   2019-03-29 05:01:14.000 7065    0d 00:13:11:000
2   2019-04-01 04:56:21.000 9518    1d 23:52:21:000
2   2019-03-30 05:04:00.000 9638    2d 00:34:29:000
2   2019-03-28 04:29:31.000 9499    1d 23:28:47:000
2   2019-03-26 05:00:44.000 10117   2d 00:03:41:000
2   2019-03-24 04:57:03.000 9933    1d 23:50:06:000
2   2019-03-22 05:06:57.000 9869    2d 00:25:01:000

Мне нужен скрипт, который суммирует Amount2 из строк, где время PickupDate находится в пределах 18 часов или 22 часов, также вычисляетстроки, которые суммируются (это должно быть сделано в пределах ID).

PickupDateTime  Amount2 DifferenceToPrevious    Amount2_18h Rows_18 Amount2_22h Rows_22
2019-04-02 04:44:19.000 6458    0d 00:13:17:000 13388   3   16854   4
2019-04-02 04:31:02.000 5385    0d 02:34:50:000 6930    2   10396   3
2019-04-02 01:56:12.000 1545    0d 18:06:18:000 1545    1   12516   3
2019-04-01 07:49:54.000 3466    1d 02:23:51:000 3466    1   3466    1
2019-03-31 05:26:03.000 7505    0d 00:13:53:000 13751   3   16742   4
2019-03-31 05:12:10.000 5080    0d 03:28:18:000 6246    2   9237    3
2019-03-31 01:43:52.000 1166    0d 18:02:49:000 1166    1   4157    2
2019-03-30 07:41:03.000 2991    1d 02:39:49:000 2991    1   2991    1
2019-04-01 04:56:21.000 9518    1d 23:52:21:000 9518    1   9518    1
2019-03-30 05:04:00.000 9638    2d 00:34:29:000 9638    1   9638    1
2019-03-28 04:29:31.000 9499    1d 23:28:47:000 9499    1   9499    1
2019-03-26 05:00:44.000 10117   2d 00:03:41:000 10117   1   10117   1
2019-03-24 04:57:03.000 9933    1d 23:50:06:000 9933    1   9933    1
2019-03-22 05:06:57.000 9869    2d 00:25:01:000 9869    1   9869    1

Ответы [ 4 ]

1 голос
/ 10 апреля 2019

Хотя запрос @ Michał Turczyn предоставит правильные данные, он также потребует 5 сканирований (1 основное + 4 на подзапрос).Вы можете сделать это более эффективно с помощью всего одного дополнительного сканирования:

declare @tbl table (ID int,  PickupDateTime datetime2(3), Amount2 int)
insert into @tbl values
(1,   '2019-04-02 04:44:19.000', 6458),
(1,   '2019-04-02 04:31:02.000', 5385),
(1,   '2019-04-02 01:56:12.000', 1545),
(1,   '2019-04-01 07:49:54.000', 3466),
(1,   '2019-03-31 05:26:03.000', 7505),
(1,   '2019-03-31 05:12:10.000', 5080),
(1,   '2019-03-31 01:43:52.000', 1166),
(1,   '2019-03-30 07:41:03.000', 2991),
(1,   '2019-03-29 05:01:14.000', 7065),
(2,   '2019-04-01 04:56:21.000', 9518),
(2,   '2019-03-30 05:04:00.000', 9638),
(2,   '2019-03-28 04:29:31.000', 9499),
(2,   '2019-03-26 05:00:44.000', 10117),
(2,   '2019-03-24 04:57:03.000', 9933),
(2,   '2019-03-22 05:06:57.000', 9869);

SELECT pickup.*, subCalc.*
  FROM @tbl pickup
 CROSS 
 APPLY (SELECT SUM(incl.include18) AS count18
             , SUM(incl.include18 * sub.Amount2) AS amount18
             , SUM(incl.include22) AS count22
             , SUM(incl.include22 * sub.Amount2) AS amount22
          FROM @tbl sub
         CROSS
         APPLY (SELECT IIF(DATEADD(HOUR, -18, pickup.pickupdatetime) <= sub.PickupDateTime, 1, 0) AS include18
                     , IIF(DATEADD(HOUR, -22, pickup.pickupdatetime) <= sub.PickupDateTime, 1, 0) AS include22
             ) incl
         WHERE pickup.PickupDateTime >= sub.PickupDateTime
           AND pickup.id = sub.id
     ) subCalc
ORDER BY pickup.PickupDateTime DESC

Рабочий пример для dbfiddle .

1 голос
/ 10 апреля 2019

Данные испытаний:

declare @tbl table (ID int,  PickupDateTime datetime2(3), Amount2 int)
insert into @tbl values
(1,   '2019-04-02 04:44:19.000', 6458),
(1,   '2019-04-02 04:31:02.000', 5385),
(1,   '2019-04-02 01:56:12.000', 1545),
(1,   '2019-04-01 07:49:54.000', 3466),
(1,   '2019-03-31 05:26:03.000', 7505),
(1,   '2019-03-31 05:12:10.000', 5080),
(1,   '2019-03-31 01:43:52.000', 1166),
(1,   '2019-03-30 07:41:03.000', 2991),
(1,   '2019-03-29 05:01:14.000', 7065),
(2,   '2019-04-01 04:56:21.000', 9518),
(2,   '2019-03-30 05:04:00.000', 9638),
(2,   '2019-03-28 04:29:31.000', 9499),
(2,   '2019-03-26 05:00:44.000', 10117),
(2,   '2019-03-24 04:57:03.000', 9933),
(2,   '2019-03-22 05:06:57.000', 9869);

Запрос, чтобы получить желаемые результаты. Ключ заключается в использовании подзапросов с соответствующими предложениями where:

select t1.*,
       (select count(*) from @tbl t2
        where dateadd(hour, -18, t1.pickupdatetime) <= t2.PickupDateTime
        and t1.PickupDateTime >= t2.PickupDateTime
        and t1.id = t2.id) Rows_18,
       (select sum(Amount2) from @tbl t2
        where dateadd(hour, -18, t1.pickupdatetime) <= t2.PickupDateTime
        and t1.PickupDateTime >= t2.PickupDateTime
        and t1.id = t2.id) Amount2_18,
       (select count(*) from @tbl t2
        where dateadd(hour, -22, t1.pickupdatetime) <= t2.PickupDateTime
        and t1.PickupDateTime >= t2.PickupDateTime
        and t1.id = t2.id) Rows_22,
       (select sum(Amount2) from @tbl t2
        where dateadd(hour, -22, t1.pickupdatetime) <= t2.PickupDateTime
        and t1.PickupDateTime >= t2.PickupDateTime
        and t1.id = t2.id) Amount2_22
from @tbl t1
order by t1.PickupDateTime desc
0 голосов
/ 10 апреля 2019

тебе нужно что-то подобное?

select * from 
(    Select PickupDateTime  sum(Amount2) as sum_amount_18, Count(*) as n_lines_summed18
    From table
    WHERE PickupDateTime <=  DateDiff(HOUR, -18, GetDate())
    Group by PickupDateTime  )X join 
(    Select PickupDateTime  sum(Amount2) as sum_amount_22, Count(*) as n_lines_summed22
    From table
    WHERE PickupDateTime <=  DateDiff(HOUR, -22, GetDate())
    Group by PickupDateTime  )y on X.PickupDateTime  =  Y.PickupDateTime  
0 голосов
/ 10 апреля 2019
Select sum(Amount2) as sum_amount_2, Count(*) as n_lines_summed
From table
WHERE PickupDateTime between DateDiff(HOUR, -22, GetDate()) and DateDiff(HOUR, -18, GetDate())
Group by Id

что-то подобное? довольно просто, я думаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...