我有一个存储Id,日期时间和整数新月值的表。该值增加,直到它“破坏”并返回到0附近的值。例如:... 1000、1200、1350、8、10、25 ... 我需要计算一下这种“溢出”发生了多少次,但是……我说的是每天存储20万行的表! 我已经解决了!但是使用带有游标的过程,并使用while循环对其进行迭代。但是我知道这不是更快的方法。
有人可以帮助我找到其他方式吗? 谢谢!
->
表结构: ID Bigint主键,CreatedAt DateTime,值不为Null Int。
问题: 如果两个连续行之间的Delta值<0,则增加一个计数器。 表格每天有20万新行。 不允许触发。
[第一次编辑]
Table has the actual structure:
CREATE TABLE ValuesLog (
Id BIGINT PRIMARY KEY,
Machine BIGINT,
CreatedAt DATETIME,
Value INT
)
我需要: 检查某些[机器]的[值]何时突然降低。
据说有些用户使用过LEAD / LAG。但这有一个问题...如果我选择了很多机器,那么LEAD / LAG功能就不会在乎“它是什么机器”。因此,如果我发现机器1和机器2,如果机器1增加但机器2减少,则LEAD / LAG会给我一个误报。
因此,我的表实际上是什么样的: Many rows of the actual table
(上面的图像是为3台或4台机器选择的。但是,在此示例中,机器并没有弄乱。但是可能会发生!在这种情况下,LEAD / LAG不在乎上面的行是否是机器-1或machine-2)
我想要什么: 在第85行中,[value]中断并重新启动。我想统计一下每次发生的情况,即所选择的机器。 所以: “ Machine-1重新启动了6次... Machine-9重新启动了10次...”
我做了一些类似的事情:
CREATE PROCEDURE CountProduction @Machine INT_ARRAY READONLY, @Start DATETIME, @End DATETIME AS
SET NOCOUNT ON
-- Declare counter and insert start values
DECLARE @Counter TABLE(
machine INT PRIMARY KEY,
lastValue BIGINT DEFAULT 0,
count BIGINT DEFAULT 0
)
INSERT INTO @Counter(machine) SELECT n FROM @Machine
-- Declare cursor to iteract over results of values log
DECLARE valueCursor CURSOR LOCAL FOR
SELECT
Value,
Aux.LastValue,
Aux.count
FROM
ValueLog,
@Machine AS Machine,
@Counter AS Counter
WHERE
ValueLog.Machine = Machine.n
AND Counter.machine = ValueLog.Machine
AND ValueLog.DateCreate BETWEEN @Start AND @End;
-- Start iteration
OPEN valueCursor
DECLARE @RowMachine INT
DECLARE @RowValue BIGINT
DECLARE @RowLastValue BIGINT
DECLARE @RowCount BIGINT
FETCH NEXT FROM valueCursor INTO @RowMachine, @RowValue, @RowLastValue, @RowCount
-- Iteration
DECLARE @increment INT
WHILE @@FETCH_STATUS = 0
BEGIN
IF @RowValue < @RowLastValue
SET @increment = 1
ELSE
SET @increment = 0
-- Update counters
UPDATE
@Counter
SET
lastValue = @RowValue,
count = count + @increment
WHERE
inj = @RowMachine
-- Proceed to iteration
FETCH NEXT FROM valueCursor INTO @RowMachine, @RowValue, @RowLastValue, @RowCount
END
-- Closing iteration
CLOSE valueCursor
DEALLOCATE valueCursor
SELECT machine, count FROM @Counter
答案 0 :(得分:0)
使用LEAD()。如果下一行<当前行,则计算该次出现。
答案 1 :(得分:0)
使用建议的@ jeroen-mostert解决
DECLARE @Start DATETIME
DECLARE @End DATETIME
SET @Start = '2019-01-01'
SET @End = GETDATE()
SELECT
Machine,
COUNT(DeltaValue) AS Prod
FROM
(SELECT
Log.Machine,
Log.Value - LAG(Log.Value) OVER (PARTITION BY Log.Machine ORDER BY Log.Id) AS DeltaValue
FROM
ValueLog AS Log,
(SELECT
Id,
Machine,
Value
FROM
ValueLog
) AS AuxLog
WHERE
AuxLog.Id = Log.Id
AND Proto.DateCreate BETWEEN @Start AND @End
AND Proto.Machine IN (1, 9, 10)
) as TB1
WHERE
DeltaValue < 0
GROUP BY
Machine
ORDER BY
Machine
在这种情况下,内部的LAG / LEAD函数不会弄乱内容(创建视图时由于某种原因发生的事情……我将在以后尝试理解)。
谢谢大家!我是DB的新手,这个问题使我整整疯狂了。