TSQL — Сравнить два столбца с самосоединением — Вычислить разницу между итогом за вчерашний день и итогом за сегодняшний день

#sql #tsql #sql-server-2014

#sql #tsql #sql-server-2014

Вопрос:

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

Требования:

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

Проблема

Приведенный ниже код возвращает ноль, и я не понимаю, почему.

Почему он не вычисляется и что я должен сделать, чтобы соответствовать требованиям, пожалуйста?


 IF OBJECT_ID('tempdb..#t1') IS NOT NULL DROP TABLE #t1

CREATE TABLE #t1 (
 countID UNIQUEIDENTIFIER
,empCount VARCHAR(20)
,CountDate DATETIME
)

INSERT INTO #t1 (
    countID
  , empCount
  , CountDate
)
VALUES
     (NEWID(),'123000', GETDATE()) 
    ,(NEWID(),'100', '20200813')
    ,(NEWID(),'100', '20200810')

SELECT 
    today.countID
  , (CAST(today.empCount AS INT)) - (CAST(yesterday.empCount AS INT)) AS CountDiff
  , today.empCount
  , today.CountDate
FROM #t1 AS today
INNER JOIN #t1 AS yesterday ON today.countID = yesterday.countID
                                AND yesterday.CountDate > (SELECT dateadd(day,datediff(day,2,GETDATE()),0))
  

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

1. В стороне: использование значений datetime for date может быть проблематичным. У вас действительно есть какие-либо временные значения, отличные от полуночи?

2. @HABO, да, бывают случаи, когда я хотел бы знать, в какое время это произошло, чтобы убедиться, что это произошло после другого процесса.

Ответ №1:

Я думаю, вы хотите lag() :

 select t.*,
       (empcount - lag(empcount) over (order by countdate)) as diff
from #t1 t;
  

Если вам нужны только последние два дня, то:

 select top (1) t.*
from (select t.*,
             (empcount - lag(empcount) over (order by countdate)) as diff
      from #t1 t
     ) t
order by countdate desc;
  

Примечание: Это интерпретирует «вчера» как два последних дня в таблице. Если вам действительно нужны конкретно сегодняшние и вчерашние данные, то вы можете использовать where предложение:

 select top (1) t.*
from (select t.*,
             (empcount - lag(empcount) over (order by countdate)) as diff
      from #t1 t
      where countdate >= dateadd(day, -1, convert(date, getdate()))
     ) t
order by countdate desc;
  

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

1. Спасибо @GordonLinoff. Когда я изменил свой empcount на INT, это сработало. Я ценю помощь!