lau*_*ens 7 sql t-sql sql-server excel
I need to 'translate' some business logic from Excel to T-SQL, I'm having a hard time with it.
It's about figures from gates that count how many customers go IN and OUT of the stores.
All DATA you need is in the following table:
CREATE TABLE #ResultsTable
(
Datum DATETIME,
window CHAR(10),
countersOUT INT,
countersIN INT,
RESULT INT
)
INSERT INTO #ResultsTable
VALUES ('20180104 08:30:00.000', '08:30', 0, 0, 0),
('20180104 09:00:00.000', '09:00', 2, 1, 1),
('20180104 09:30:00.000', '09:30', 1, 0, 2),
('20180104 10:00:00.000', '10:00', 25, 9, 18),
('20180104 10:30:00.000', '10:30', 45, 41, 22),
('20180104 11:00:00.000', '11:00', 38, 37, 23),
('20180104 11:30:00.000', '11:30', 50, 51, 22),
('20180104 12:00:00.000', '12:00', 21, 24, 19),
('20180104 12:30:00.000', '12:30', 12, 19, 12),
('20180104 13:00:00.000', '13:00', 25, 18, 19),
('20180104 13:30:00.000', '13:30', 35, 27, 27),
('20180104 14:00:00.000', '14:00', 81, 9, 52),
('20180104 14:30:00.000', '14:30', 113, 18, 70),
('20180104 15:00:00.000', '15:00', 116, 34, 71),
('20180104 15:30:00.000', '15:30', 123, 36, 54),
('20180104 16:00:00.000', '16:00', 127, 35, 50),
('20180104 16:30:00.000', '16:30', 103, 19, 47),
('20180104 17:00:00.000', '17:00', 79, 31, 27),
('20180104 17:30:00.000', '17:30', 50, 16, 26),
('20180104 18:00:00.000', '18:00', 28, 11, 17),
('20180104 18:30:00.000', '18:30', 16, 15, 2),
('20180104 19:00:00.000', '19:00', 0, 2, 0),
('20180104 19:30:00.000', '19:30', 0, 0, 0),
('20180104 20:00:00.000', '20:00', 0, 0, 0),
('20180104 20:30:00.000', '20:30', 0, 0, 0),
('20180104 21:00:00.000', '21:00', 0, 0, 0),
('20180104 21:30:00.000', '21:30', 0, 0, 0),
('20180104 22:00:00.000', '22:00', 0, 0, 0)
select * from #ResultsTable
Run Code Online (Sandbox Code Playgroud)
'RESULT' is the column that should be calculated, based on 'countersOUT and 'countersIN'.
'countersOUT and 'countersIN' is the INPUT data you need for the calculation.
The business user made a help column in Excel to make the calculation (column AA) . . . . . . .From business point of view: this is the number of customers at the end of each half hour present in the shop.
Then, the actual calculation below: (screenshot also from Excel)
Note: the calculation makes use of the help column (col. AA)

Now my task is to make over this calculation in T-SQL.
The business user its only input data is 'countersIN' and 'countersOUT', in other words it should be achievable in T-SQL. Only, I don't manage, that's why I came to ask my question.
Lastly, I can advise to have a look at the Excel file (mediafire link) http://www.mediafire.com/file/mtdvlgmmbj3f8dd/Example_20190725_SQLforum.xlsx/file
Thanks a lot in advance for any help
小智 1
这是使用游标的解决方案。没有好的风格但有效,因为你在行中移动。属性 [RESULT_by_Cursor] 是与目标值相比计算得出的属性。
顺便说一句:你的 SQL 示例有一个错误,输入和输出列是扭曲的。
CREATE TABLE #ResultsTable
(
Datum DATETIME,
window CHAR(10),
countersIN INT,--countersOUT INT,
countersOUT INT,--countersIN INT,
RESULT INT,
RESULT_by_Cursor INT,
countersIN_corrected INT
);
INSERT INTO #ResultsTable
VALUES ('20180104 08:30:00.000', '08:30', 0, 0, 0, NULL, NULL),
('20180104 09:00:00.000', '09:00', 2, 1, 1, NULL, NULL),
('20180104 09:30:00.000', '09:30', 1, 0, 2, NULL, NULL),
('20180104 10:00:00.000', '10:00', 25, 9, 18, NULL, NULL),
('20180104 10:30:00.000', '10:30', 45, 41, 22, NULL, NULL),
('20180104 11:00:00.000', '11:00', 38, 37, 23, NULL, NULL),
('20180104 11:30:00.000', '11:30', 50, 51, 22, NULL, NULL),
('20180104 12:00:00.000', '12:00', 21, 24, 19, NULL, NULL),
('20180104 12:30:00.000', '12:30', 12, 19, 12, NULL, NULL),
('20180104 13:00:00.000', '13:00', 25, 18, 19, NULL, NULL),
('20180104 13:30:00.000', '13:30', 35, 27, 27, NULL, NULL),
('20180104 14:00:00.000', '14:00', 81, 9, 52, NULL, NULL),
('20180104 14:30:00.000', '14:30', 113, 18, 70, NULL, NULL),
('20180104 15:00:00.000', '15:00', 116, 34, 71, NULL, NULL),
('20180104 15:30:00.000', '15:30', 123, 36, 54, NULL, NULL),
('20180104 16:00:00.000', '16:00', 127, 35, 50, NULL, NULL),
('20180104 16:30:00.000', '16:30', 103, 19, 47, NULL, NULL),
('20180104 17:00:00.000', '17:00', 79, 31, 27, NULL, NULL),
('20180104 17:30:00.000', '17:30', 50, 16, 26, NULL, NULL),
('20180104 18:00:00.000', '18:00', 28, 11, 17, NULL, NULL),
('20180104 18:30:00.000', '18:30', 16, 15, 2, NULL, NULL),
('20180104 19:00:00.000', '19:00', 0, 2, 0, NULL, NULL),
('20180104 19:30:00.000', '19:30', 0, 0, 0, NULL, NULL),
('20180104 20:00:00.000', '20:00', 0, 0, 0, NULL, NULL),
('20180104 20:30:00.000', '20:30', 0, 0, 0, NULL, NULL),
('20180104 21:00:00.000', '21:00', 0, 0, 0, NULL, NULL),
('20180104 21:30:00.000', '21:30', 0, 0, 0, NULL, NULL),
('20180104 22:00:00.000', '22:00', 0, 0, 0, NULL, NULL)
-- PDO: Apply Cursor to run through datasets
DECLARE @Datum DATETIME,
@window CHAR(10),
@countersOUT INT, -- U
@countersIN INT, -- V
@countersOUT_next INT, -- V + 1 row
@countersOUT_nextnext INT, -- V + 2 rows
@countersIN_corrected INT,
@RESULT_by_Cursor INT; --AA
DECLARE C_Tag CURSOR FAST_FORWARD FOR
SELECT Datum,
window,
countersOUT,
countersIN
FROM #ResultsTable
ORDER BY Datum ASC
;
-- PDO: Cursor open and first fetch
SET @countersIN_corrected=0;
SET @RESULT_by_Cursor=0;
OPEN C_Tag
FETCH NEXT FROM C_Tag INTO @Datum,
@window,
@countersOUT,
@countersIN
;
WHILE @@FETCH_STATUS=0
BEGIN
-- PDO: Get upcoming data in case we need them
SET @countersOUT_next = ISNULL((SELECT TOP 1 r.countersOUT
FROM #ResultsTable r
WHERE r.Datum > @Datum
ORDER BY r.Datum
),0)
;
SET @countersOUT_nextnext = ISNULL((SELECT TOP 1 r.countersOUT
FROM #ResultsTable r
WHERE r.Datum > (SELECT TOP 1 r2.Datum
FROM #ResultsTable r2
WHERE r2.Datum > @Datum
ORDER BY r2.Datum
)
ORDER BY r.Datum
),0)
;
-- PDO: Compute correction according to Formula
SET @countersIN_corrected=IIF(@RESULT_by_Cursor + @countersIN - @countersOUT < 0 ,
@countersOUT ,
IIF(@RESULT_by_Cursor + @countersIN - @countersOUT > (@countersOUT_next + @countersOUT_nextnext) ,
@countersOUT_next + @countersOUT_nextnext + @countersOUT - @RESULT_by_Cursor ,
@countersIN
)
);
-- PDO: Compute Result by cursor
SET @RESULT_by_Cursor=@RESULT_by_Cursor + @countersIN_corrected - @countersOUT;
-- PDO: Update Table with computed result
UPDATE #ResultsTable
SET RESULT_by_Cursor=@RESULT_by_Cursor,
countersIN_corrected=@countersIN_corrected
WHERE Datum=@Datum
;
FETCH NEXT FROM C_Tag INTO @Datum,
@window,
@countersOUT,
@countersIN
;
END -- @@Fetch_Status C_Tag
CLOSE C_Tag;
DEALLOCATE C_Tag;
-- PDO: Clean Up
select * from #ResultsTable;
DROP TABLE #ResultsTable;
Run Code Online (Sandbox Code Playgroud)