Использование while l oop для вычисления разницы в двух строках и вставки результатов во временную таблицу - PullRequest
1 голос
/ 28 апреля 2020

У меня есть таблица, которая содержит данные Covid по округам. Мне нужно провести l oop через таблицу, чтобы вычислить разницу в количестве случаев и смертей по количеству имен за предыдущий день в то же время. Например. Я знаю, что общее количество дел в 15:00 3/20 для камер равно 4, а для 3/19 - 1. Разница составляет 3. Мне нужно вставить COUNTYNAME, DateReported & Difference в случае подсчета в временная таблица для каждой строки в моей таблице. Конечно, это вымышленные данные.

CID    COUNTYNAME     Cases  Deaths         DateReported    
---------------------------------------------------------------------           
1   |   Baldwin     |   1   |   0   |   2020-03-19 12:00:00.000     
2   |   Cook        |   1   |   0   |   2020-03-19 12:00:00.000     |
3   |   Chambers    |   1   |   0   |   2020-03-19 12:00:00.000     |
4   |   Total       |   3   |   0   |   2020-03-19 12:00:00.000     |
5   |   Baldwin     |   1   |   0   |   2020-03-19 15:00:00.000     |
6   |   Cook        |   2   |   0   |   2020-03-19 15:00:00.000     |
7   |   Chambers    |   4   |   0   |   2020-03-19 15:00:00.000     |
8   |   Elmore      |   1   |   0   |   2020-03-19 15:00:00.000     |
9   |   Total       |   8   |   0   |   2020-03-19 15:00:00.000     |
10  |   Baldwin     |   1   |   0   |   2020-03-20 12:00:00.000     |
11  |   Cook        |   2   |   0   |   2020-03-20 12:00:00.000     |
12  |   Chambers    |   4   |   0   |   2020-03-20 12:00:00.000     |
13  |   Clarke      |   1   |   0   |   2020-03-20 12:00:00.000     |
14  |   Elmore      |   1   |   0   |   2020-03-20 12:00:00.000     |
15  |   Total       |   9   |   0   |   2020-03-20 12:00:00.000     |
16  |   Baldwin     |   1   |   0   |   2020-03-20 15:00:00.000     |
17  |   Cook        |   2   |   0   |   2020-03-20 15:00:00.000     |
18  |   Chambers    |   4   |   0   |   2020-03-20 15:00:00.000     |
19  |   Clarke      |   1   |   0   |   2020-03-20 15:00:00.000     |
20  |   Elmore      |   2   |   0   |   2020-03-20 15:00:00.000     |
21  |   Total       |   10  |   0   |   2020-03-20 15:00:00.000     |

Вот то, что у меня есть, что, кажется, приближает меня к тому, что мне нужно, но моя таблица содержит 50 000 строк, и это занимает 5+ минут.

CREATE TABLE #tempTable1 (
CountyName varchar(50),
DateReported datetime,
DiffVal int
)
DECLARE @RowCount INT
,@HourVal int = datepart(hh,getdate())
,@PreviousDayVal date = dateadd(DD, -1, cast(getdate() as date))
--Get the number of rows in our table to loop through.
SET @RowCount = (SELECT COUNT(COUNTYNAME) FROM myCovidTable)
DECLARE @I INT
SET @I = 1

WHILE (@I <= @RowCount)
BEGIN
DECLARE @iCountyName VARCHAR(50)
,@iDateReported datetime
,@iDiffVal int
,@CountyNameVal varchar(50) = (SELECT COUNTYNAME FROM myCovidTable WHERE CID = @I)
,@CurrentDateVal datetime = (SELECT dateadd(DD, 0, cast(DateReported as date)) FROM myCovidTable WHERE CID = @I); -- The current row's DateReported value
--The date reported isn't always constant so I need to parse the date 
WITH tempTable2 
     AS (SELECT Cases,
                Cast(DateReported AS DATE) AS DateField 
         FROM   myCovidTable
         WHERE  Datepart(HH, ( DateReported )) = @HourVal
                AND COUNTYNAME = @CountyNameVal) 
SELECT @iDiffVal  = (
    SELECT  SUM (Cases)
    FROM    tempTable2 
    WHERE   DateField = @CurrentDateVal) -
    (SELECT SUM (Cases)
    FROM    tempTable2 
    WHERE   DateField = @PreviousDayVal)

-- Then we insert it into the table
SET @iDateReported = (SELECT DateReported FROM myCovidTable WHERE CID = @I)
SET @iCountyName = (SELECT COUNTYNAME FROM myCovidTable WHERE CID = @I)
SET @I = @I + 1
INSERT into #tempTable1 select @iCountyName as CountyName, @iDateReported as DateReported, @iDiffVal as DiffValue

END
SELECT * FROM #tempTable1

Результаты должны представлять собой таблицу с тремя столбцами: CountyName, DateReported и DiffVal, показывающие разницу в случаях в одно и то же время предыдущего дня по округам для каждой строки (сообщенная дата).

Ответы [ 2 ]

3 голосов
/ 28 апреля 2020

Один вариант - самостоятельное соединение:

insert into #tempTable1 (countyname, datereported, diffval)
select
    t.countyname,
    t.datereported,
    t.case - coalesce(t1.case, 0)
from mytable t
left join mytable t1
    on  t1.countyname = t.countyname
    and t1.datereported = dateadd(day, -1, t.datereported)
2 голосов
/ 28 апреля 2020

Вы можете использовать оконную функцию:

CREATE TABLE #stat
(
    CID          INT NOT NULL PRIMARY KEY,
    CountyName   VARCHAR(50) NOT NULL,
    DateReported DATETIME NOT NULL,
    Cases        INT NOT NULL,
    Deaths       INT NOT NULL
);

-- INSERT INTO #stat ...

CREATE NONCLUSTERED INDEX IX_Stat ON #stat (CountyName, DateReported) INCLUDE (Deaths, Cases);

SELECT CountyName,
       DateReported,
       CasesDiff = Cases - LAG(Cases) OVER (PARTITION BY CountyName ORDER BY DateReported),
       DeathsDiff = Deaths - LAG(Deaths) OVER (PARTITION BY CountyName ORDER BY DateReported)
FROM #stat;
...