выберите максимальную запись для каждого устройства, которая была записана на 10-й день - PullRequest
0 голосов
/ 24 августа 2018

У меня есть таблица tblActiveList, в которой есть столбцы «DeviceID» и «TimeAdded», а другая таблица tblActiveBladeLive с столбцами «DeviceID», «RecordedDate» и «Angle». Как выбрать максимальный угол для каждого устройства, записанного на 10-й день (каждое устройство можетиметь несколько ракурсов в любой день)?

Вот мой запрос на выбор 10-го дня добавления устройства

Select DeviceID, TimeAdded, TimeAdded+10 as '10TH_Day' from tblActiveList

DeviceID    TimeAdded                 10TH_Day
BL000343    2018-08-08 15:09:54.483   2018-08-18 15:09:54.483
BL000247    2018-08-08 17:03:57.593   2018-08-18 17:03:57.593

Вот 2-я таблица со всеми ракурсами за несколько месяцев от дня, когда было добавлено устройство.

Select DeviceID, RecordedDate, Angle from tblActiveBladeLive

DeviceID    RecordedDate            Angle
BL000343    2018-08-15 23:55:13.000 11.50
BL000343    2018-08-16 22:54:58.000 12.55
BL000343    2018-08-16 21:54:58.000 12.55
BL000343    2018-08-17 23:54:59.000 13.15
BL000343    2018-08-18 05:54:59.000 15.15
BL000343    2018-08-18 01:54:59.000 13.15
BL000247    2018-08-17 03:44:57.000 15.78
BL000247    2018-08-18 06:46:41.000 15.05
BL000247    2018-08-17 11:46:56.000 15.05
BL000247    2018-08-18 05:46:41.000 14.05

Вот записи, которые необходимо выбрать

DeviceID    RecordedDate            Angle
BL000343    2018-08-18 05:54:59.000 15.15
BL000247    2018-08-18 06:46:41.000 15.05

Любая помощь будет принята с благодарностью.

Ответы [ 5 ]

0 голосов
/ 24 августа 2018

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

with MaxAngle as (
    select DeviceID, RecordedDate, Angle,
        row_number() over
            (partition by DeviceID, cast(RecordedDate as date) order by Angle desc) as rn
    from tblActiveBladeLive
)
select *
from tblActiveList as l left outer join MaxAngle as a
    on      a.DeviceID = l.DeviceID
        and cast(dateadd(day, 10, a.TimeAdded) as date) = cast(l.RecordedDate as date)
        and a.rn = 1;
0 голосов
/ 24 августа 2018
SELECT 
    DeviceID 
,   RecordedDate
,   Angle
FROM (
SELECT 
    tab.DeviceID
,   tab.RecordedDate
,   tab.Angle
,   ROW_NUMBER() OVER(PARTITION BY tab.DeviceID ORDER BY RecordedDate DESC) MaxRN  
FROM @tblActiveBladeLive tab
LEFT JOIN  @tblActive ta 
    ON ta.DeviceID = tab.DeviceID 
    AND ta.TimeAdded <= tab.RecordedDate 
    AND CAST(DATEADD(DAY, 10,CAST(TimeAdded AS DATE) ) AS DATETIME) + ' 23:59:59' >= tab.RecordedDate 
) D
WHERE 
    MaxRN = 1 

Примечание:

CAST(DATEADD(DAY, 10,CAST(TimeAdded AS DATE) ) AS DATETIME) + ' 23:59:59'

Время кастаДобавлено к дате и добавлено 10 дней, затем указано время 23:59:59, чтобы убедиться, что мы получим все записи в 10-й день.

Вы можете обновить таблицу tblActiveList с правильными датами.Это сделало бы вещи более эффективными и более легкими в работе для долгосрочного использования.

0 голосов
/ 24 августа 2018

Вот как я бы это сделал:

SELECT A.DeviceID, MAX(RecordedDate) AS RecordedDate, A.Angle
FROM (SELECT tblActiveList.DeviceID, CONVERT(date,DATEADD(d,10,TimeAdded)) AS Day10, MAX(Angle) AS Angle
        FROM tblActiveList
            LEFT JOIN tblActiveBladeLive ON tblActiveList.DeviceID=tblActiveBladeLive.DeviceID AND CONVERT(date,DATEADD(d,10,TimeAdded))=CONVERT(date,RecordedDate)
        GROUP BY tblActiveList.DeviceID, TimeAdded) A
    LEFT JOIN tblActiveBladeLive B ON A.DeviceID=B.DeviceID AND A.Angle=B.Angle AND Day10=CONVERT(date,RecordedDate)
GROUP BY A.DeviceID, A.Angle

Это было написано без среды тестирования, поэтому могут быть опечатки и ошибки.Максимальный угол легко получить на 10-й день.Затем сложная часть получает метку времени, соответствующую ей.Если вам не важна часть времени и только часть даты в конечном результате, это может стать намного проще:

SELECT tblActiveList.DeviceID, CONVERT(date,DATEADD(d,10,TimeAdded)) AS Day10, MAX(Angle) AS Angle
FROM tblActiveList
    LEFT JOIN tblActiveBladeLive ON tblActiveList.DeviceID=tblActiveBladeLive.DeviceID AND CONVERT(date,DATEADD(d,10,TimeAdded))=CONVERT(date,RecordedDate)
GROUP BY tblActiveList.DeviceID, TimeAdded
0 голосов
/ 24 августа 2018

Отредактировано 1. Возникла проблема.

попробуйте это.Похоже, тот же подход упомянут выше, но, возможно, он может быть полезен:

WITH device_10thDay as
(
Select 
    DeviceID, CONVERT(VARCHAR(10), DATEADD(day, 10, TimeAdded), 103) as 'Tenth_Day' 
from tblActiveList
)

Select 
    tenDays.DeviceID, 
    CONVERT(VARCHAR(10), RecordedDate, 103) as RecordedDate, 
    MAX(Angle) as Angle
from device_10thDay tenDays 
left JOIN tblActiveBladeLive tbl on tenDays.DeviceID = tbl.DeviceID and tenDays.Tenth_Day = CONVERT(VARCHAR(10), RecordedDate, 103) 
group by 
    tenDays.DeviceID, 
    CONVERT(VARCHAR(10), RecordedDate, 103)
0 голосов
/ 24 августа 2018

Я немного смущен вашими данными и тем, что вы ищете. Вам нужно будет использовать JOIN, CTE, вероятно, GROUP BY хотя бы один раз. Скорее всего, коррелированный подзапрос. Если вы сможете перефразировать ваш вопрос немного лучше, это поможет. Также добавьте, какой движок SQL вы используете, если знаете.

...