2016-09-23 2 views
2

Чтобы понять вопрос, я объясню ожидаемый результат. У меня есть таблица db, где я сохраняю некоторые данные о деятельности текущего дня. Затем я хочу суммировать некоторые числовые поля и последний регистр текстовых полей, используя фильтр между двумя датами.Фильтрация запроса с помощью подзапросов

Пример:

 •DB TABLE 

    ID|CALLS|RESULT | DATE 

    1 | 2 |FAIL |15/09/16 
    1 | 1 |ERROR |16/09/16 
    1 | 3 |OK  |17/09/16 


     •SUM BETWEEN 15 and 17 

ID|TOTAL CALLS|LAST RESULT 
1 | 6  | OK 

    •SUM BETWEEN 15 and 16 

ID|TOTAL CALLS|LAST RESULT 
1 | 3  | ERROR 

-Would это может быть решение?

SELECT DISTINCT ID, 
TOTAL_CALLS=SUM(CALLS), 
LAST_RESULT= (
    SELECT RESULT FROM TABLE T2 where T2.DATE between MIN(T1.DATE) and MAX (T1.DATE) and T1.ID=T2.ID 
) 

FROM TABLE T1 
WHERE 
TIME BETWEEN 15/09/16 and 17/09/16 
GROUP BY ID 

спасибо!

С уважением

+0

, что ваш окончательный выходной сигнал, основанный на вашей таблице образца – TheGameiswar

+0

Требуемое решение будет 1 (ID) | 6 (ВЫЗОВЫ) | ОК (РЕЗУЛЬТАТ). В случае, если TIME LAST DATE были 16/09/16, решение будет 1 (ID) | 3 (CALLS) | ОШИБКА (РЕЗУЛЬТАТ). Извините за текстовый формат. Большое спасибо :) – Rachel

ответ

1

Используйте нижеследующий запрос.

;WITH cte_1 
AS 
(SELECT ID,SUM(CALLS)OVER(PARTITION BY ID) [TOTAL CALLS] 
,Result [LAST RESULT] 
,ROW_NUMBER()OVER(PARTITION BY ID ORDER BY [DATE] desc) RNO 
from #YourTable T 
WHERE [DATE] between '09/15/2016' AND '09/16/16') 
SELECT ID,[TOTAL CALLS],[LAST RESULT] 
FROM cte_1 
WHERE Rno=1 
+0

Он не будет работать с несколькими значениями в столбце Идентификатор. –

+0

Практически там, но мне нужно сгруппировать по ID. Существует много разных идентификаторов, поэтому основным запросом должен быть SELECT DISTINCT. Если я использую эту структуру, я должен использовать GROUP BY DATE и отображать более одной строки на ID. Спасибо !! – Rachel

+0

используйте обновленный скрипт. –

0
SELECT ID, SUM(CALLS), MAX(CASE WHEN RNO=1 THEN RESULT END) 
FROM (
    SELECT *, ROW_NUMBER()OVER(PARTITION BY ID ORDER BY [DATE] desc) RNO 
    FROM tbl T1 
    WHERE 
    DATE BETWEEN '15/09/16' and '17/09/16' 
) A 
GROUP BY ID 

Этот запрос имеет лучший план, то решение, предложенное УННИКРИШНАН R

Просто сравните:

;with tbl(ID, CALLS, RESULT, DATE) as (
    select 1, 2, 'FAIL', '15/09/16' union all 
    select 1, 1, 'ERROR', '16/09/16' union all 
    select 1, 3, 'OK', '17/09/16' union all 
    select 2, 1, 'OK', '17/09/16' 
) 
, cte_1 
AS 
(SELECT ID,SUM(CALLS)OVER(PARTITION BY ID) [TOTAL CALLS] 
,Result [LAST RESULT] 
,ROW_NUMBER()OVER(PARTITION BY ID ORDER BY [DATE] desc) RNO 
from tbl T 
WHERE [DATE] between '15/09/16' AND '16/09/16') 
SELECT ID,[TOTAL CALLS],[LAST RESULT] 
FROM cte_1 
WHERE Rno=1 

Стоимость 0,02278908

;with tbl(ID, CALLS, RESULT, DATE) as (
    select 1, 2, 'FAIL', '15/09/16' union all 
    select 1, 1, 'ERROR', '16/09/16' union all 
    select 1, 3, 'OK', '17/09/16' union all 
    select 2, 1, 'OK', '17/09/16' 
) 
SELECT ID, SUM(CALLS), MAX(CASE WHEN RNO=1 THEN RESULT END) 
FROM (
    SELECT *, ROW_NUMBER()OVER(PARTITION BY ID ORDER BY [DATE] desc) RNO 
    FROM tbl T1 
    WHERE 
    DATE BETWEEN '15/09/16' and '17/09/16' 
) A 
GROUP BY ID 

Стоимость 0,01138172

+0

Если вы видите план, оба запроса берут ту же стоимость. –

+0

@Unnikrishnan R Вы ошибаетесь. Они будут иметь одинаковую стоимость только тогда, когда все тестовые данные состоят из единственного идентификатора. Добавьте другие данные в данные, и вы увидите, что ваши затраты будут расти. – Sergey

0

Вы можете использовать TOP 1 с галстуками с упорядочением, чтобы получить то, что вам нужно:

DECLARE @dFrom date = '2016-09-15', 
     @dTo date = '2016-09-16' 

SELECT TOP 1 WITH TIES 
        ID, 
        SUM(CALLS) OVER (PARTITION BY ID) [TOTAL CALLS], 
        RESULT [LAST RESULT] 
FROM YourTable 
WHERE [DATE] between @dFrom and @dTo 
ORDER BY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [DATE]) DESC 
0

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

DECLARE @FromDate DATETIME= '15 SEP 2016' 

DECLARE @ToDate DATETIME= '16 SEP 2016' 

SELECT ID , SUM(CALLS) , (SELECT RESULT 
          FROM #yourTable 
          WHERE [DATE] = @ToDate 
         ) RESULT 
FROM **#yourTable** 
WHERE [DATE] BETWEEN @FromDate AND @ToDate 
GROUP BY ID